执行 Ienumerable.Sum() 方法时出现错误。

发布于 2024-09-15 01:48:44 字数 1076 浏览 6 评论 0原文

为什么下面的代码不起作用?我收到以下错误。

无法将类型“V”隐式转换为 int。

private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart)
{
    var result = from t in dt.AsEnumerable()
                 group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
                 orderby g.Key.type
                 select new
                 {
                     Item_Type = g.Key.type.ToString(),
                     Amount = seriesItem.IsSum 
                          ? g.Sum(s => s.Field<V>(seriesItem.ValueMapping)) 
                          : g.Count()
                 };

    foreach (var g in result) 
    { 
        chart.Add(new DataItem(g.Item_Type, double.Parse(g.Amount.ToString()))
                  { 
                      IsSum = seriesItem.IsSum, 
                      IsDisplayCurrency = seriesItem.IsDisplayCurrency 
                  }); 
    }
    return chart;
}

Why isn't the below code working? I am getting the following error.

Cannot implicitly convert type 'V' to int.

private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart)
{
    var result = from t in dt.AsEnumerable()
                 group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
                 orderby g.Key.type
                 select new
                 {
                     Item_Type = g.Key.type.ToString(),
                     Amount = seriesItem.IsSum 
                          ? g.Sum(s => s.Field<V>(seriesItem.ValueMapping)) 
                          : g.Count()
                 };

    foreach (var g in result) 
    { 
        chart.Add(new DataItem(g.Item_Type, double.Parse(g.Amount.ToString()))
                  { 
                      IsSum = seriesItem.IsSum, 
                      IsDisplayCurrency = seriesItem.IsDisplayCurrency 
                  }); 
    }
    return chart;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紫瑟鸿黎 2024-09-22 01:48:44

问题是您试图对 V 类型的所有值求和。

s.Field(...) 返回 V 类型的值,因此选择器匿名函数 s=> s.Field(...) 也返回 V 类型的值。但是,g.Sum(...) 需要一个返回值 1 的选择器函数以下类型:decimaldoublefloatintlong (或其可空对应项)。无法从类型 V 隐式转换为其中任何类型。

如果值映射列始终属于特定类型,则显式使用该类型而不是泛型类型 V。

The problem is that you're trying to sum over all values of type V.

s.Field<V>(...) is returning a value of type V so the selector anonymous function s => s.Field<V>(...) is also returning a value of type V. However, g.Sum(...) requires a selector function that returns values of one of the following types: decimal, double, float, int, long (or their nullable counterparts). It is not possible to implicitly cast from type V to any of those types.

If the value mapping column is always of a particular type then use that type explicitly instead of the generic type V.

裸钻 2024-09-22 01:48:44

看看你的代码,我猜这段代码返回了一个 V 类型的值:

s => s.Field<V>(seriesItem.ValueMapping)

如果是这样的话,假设 V 类型没有限制(它可以是任何东西,对象,字符串等)编译器将无法找出哪个重载的 Enumerable.Sum() 方法来调用,因此编译器错误。

假设 V 的类型仅在运行时已知(因此您不能简单地将 V 限制为 int/decimal/double 等),如何将委托添加到可用于从 V 类型的对象返回 int 的方法?例如:

private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart, Func<V, int> convertV)
    {
        var result = from t in dt.AsEnumerable()
                     group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
                     orderby g.Key.type
                     select new
                     {
                         Item_Type = g.Key.type.ToString(),
                         Amount = seriesItem.IsSum ? g.Sum(s => convertV(s.Field<V>(seriesItem.ValueMapping))) : g.Count()
                     };

然后你将责任推给调用者(它知道类型 T 和 V)来弄清楚如何将 V 转换为 int。

Looking at your code, I'm guess this bit of code returns a value of type V:

s => s.Field<V>(seriesItem.ValueMapping)

if that's the case, given that there's no constraint on the type V (it could be anything, object, string, etc. etc.) the compiler won't be able to figure out which of the overloaded Enumerable.Sum() method to invoke, hence the compiler error.

Assuming that V's type is known only at runtime (so you can't simply constraint V to int/decimal/double, etc) how about add a delegate to the method which you can use to return an int from an object of type V? e.g:

private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart, Func<V, int> convertV)
    {
        var result = from t in dt.AsEnumerable()
                     group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
                     orderby g.Key.type
                     select new
                     {
                         Item_Type = g.Key.type.ToString(),
                         Amount = seriesItem.IsSum ? g.Sum(s => convertV(s.Field<V>(seriesItem.ValueMapping))) : g.Count()
                     };

then you push the responsibility to the caller (which would know the types T and V) to figure out how to convert V to an int.

苦妄 2024-09-22 01:48:44

g.Count() 返回一个 int

IsSum ? g.Sum() :g.Count() 必须是一个 int

,所以 g.Sum() 必须是一个 int

,所以 V 必须是一个

int没有什么(除了这个推导)可以阻止 V 成为十进制或其他任何东西,因此会出现编译器错误消息。

要修复:以下任一操作:

  • 删除 V 并获取 int 结果
  • 删除 g.Count()
  • 将 g.Count() 强制转换为 double 并将 V 的类型修复为 double。

最后一个有一个额外的好处,您可以稍后在方法中删除双重转换代码。


@丹尼尔·伦肖

List<decimal> source = new List<decimal>();
int result = source.Sum<decimal>();  //compile error
  //Cannot implicitly convert type 'decimal' to 'int'

g.Count() returns an int

IsSum ? g.Sum() : g.Count() must be an int

so g.Sum() must be an int

so V must be an int

There is nothing (other than this deduction) that stops V from being a decimal or anything else, hence the compiler error message.

To fix: Any of these:

  • remove V and get int results
  • remove g.Count()
  • cast g.Count() to double and fix V's type as double.

This last one has the added benefit that you can remove the double conversion code later in the method.


@Daniel Renshaw

List<decimal> source = new List<decimal>();
int result = source.Sum<decimal>();  //compile error
  //Cannot implicitly convert type 'decimal' to 'int'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文