【问题标题】:How to get linq sum of IEnumerable<object>如何获得 IEnumerable<object> 的 linq 总和
【发布时间】:2013-03-14 18:42:36
【问题描述】:

如何获得 IEnumerable 对象集合中的数字总和?我确信基础类型将始终是数字,但类型是在运行时确定的。

IEnumerable<object> listValues = data.Select(i => Convert.ChangeType(property.GetValue(i, null), columnType));

之后我希望能够做到以下几点(以下有错误:“无法解析方法总和”):

var total = listValues.Sum();

有什么想法吗?谢谢。

【问题讨论】:

  • 为什么在运行时确定确切的类型?这听起来很可疑!
  • 如果类型是在运行时确定的,这听起来像是泛型的工作。您是否有权创建IEnumerable&lt;object&gt; listValues?你能把它改成IEnumerable&lt;T&gt; where T : struct, IConvertible吗?
  • @Tory - 是的,我有权创建 IEnumerable,但我不知道如何进行您建议的更改。我是泛型世界的新手,请提供一个例子,谢谢。

标签: c# .net generics reflection


【解决方案1】:

如果你知道确切的类型总是数字类型,你应该可以使用类似的东西:

double total = listValues.Sum(v => Convert.ToDouble(v));

这会起作用,因为Convert.ToDouble 将寻找IConvertible,这是由核心数字类型实现的。您正在强制类型为 double 而不是原始类型。

【讨论】:

  • 请记住,这可能会引发InvalidCastException,例如字符串和其他对象!
  • @ebeeb - 没错,该调用之前的代码确保只有数字类型到达该点。
  • Reed - 您的解决方案很简单,效果很好,但我想保留原始类型。
  • @Mike 问题是没有办法指定编译时类型,甚至无法正确设置变量。您可以(可能)将其放入object,但这不会很有用...
【解决方案2】:

您可以使用表达式树来生成所需的添加函数,然后折叠您的输入列表:

private static Func<object, object, object> GenAddFunc(Type elementType)
{
    var param1Expr = Expression.Parameter(typeof(object));
    var param2Expr = Expression.Parameter(typeof(object));
    var addExpr = Expression.Add(Expression.Convert(param1Expr, elementType), Expression.Convert(param2Expr, elementType));
    return Expression.Lambda<Func<object, object, object>>(Expression.Convert(addExpr, typeof(object)), param1Expr, param2Expr).Compile();
}

IEnumerable<object> listValues;
Type elementType = listValues.First().GetType();
var addFunc = GenAddFunc(elementType);

object sum = listValues.Aggregate(addFunc);

注意,这要求输入列表不为空,但它的优点是可以在结果中保留元素类型。

【讨论】:

  • 您的解决方案运行良好!只是试图理解整个概念。谢谢。
【解决方案3】:

转换为一种类型。说,十进制。

data.Select(i => Convert.ToDecimal(property.GetValue(i, null)).Sum();

【讨论】:

    【解决方案4】:

    你可以使用动态的,完美的工作:

        listValues.Sum(x => (dynamic)x);
    

    【讨论】:

    • 在我的场景中,此解决方案仅在底层类型为 int 时才有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2014-01-23
    • 1970-01-01
    相关资源
    最近更新 更多