You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建表达式实现C#列表单个属性求和?遇参数数量错误

问题:构建Sum表达式时提示“调用Sum方法时提供的参数数量不正确”

尝试为列表属性创建表达式时遇到错误:

错误:调用Sum方法时提供的参数数量不正确

使用的代码如下:

ParameterExpression argParam = Expression.Parameter(typeof(T), "s");

property1 = typeof(T).GetProperty(nameof(Srt));
property2 = property1.PropertyType.GetProperty(Srt.Srtd));
propertyExp1 = Expression.Property(argParam, property1);
propertyExp = Expression.Property(propertyExp1, property2);

// in propertyExp I got {s.Srt.Srtd}

ParameterExpression argX = Expression.Parameter(typeof(Srtd), "x");
var prt1= typeof(Srtd).GetProperty(nameof(Srtd.Elt));
var prtExp= Expression.Property(argX, prt1);

// in prtExp I got {x.Elt}

var method = typeof(System.Linq.Enumerable).GetMethod("Sum", new[] { typeof(IEnumerable<decimal?>) });
var exp2 = Expression.Call(method, propertyExp, prtExp);

目标是生成类似 {s.Srt.Srtd.Sum(x=>x.Elt)} 的表达式,求解决方法。


解决方案

问题核心在于两点:

  1. 获取的Sum方法重载不符合需求:你当前获取的是仅接受IEnumerable<decimal?>的无参数Sum重载,但实际需要的是带selector委托的重载(即Sum<TSource>(this IEnumerable<TSource>, Func<TSource, decimal?>))。
  2. Expression.Call的参数逻辑错误:未正确构建selector的Lambda表达式,也未匹配扩展方法的调用参数规则。

修正步骤如下:

  1. 构建selector的Lambda表达式
    把x => x.Elt转换成表达式树结构:
ParameterExpression argX = Expression.Parameter(typeof(Srtd), "x");
var prt1 = typeof(Srtd).GetProperty(nameof(Srtd.Elt));
var prtExp = Expression.Property(argX, prt1);
// 生成x => x.Elt的Lambda表达式
var selectorLambda = Expression.Lambda<Func<Srtd, decimal?>>(prtExp, argX);
  1. 获取正确的Sum泛型重载方法
    通过筛选找到带两个参数的Sum方法定义,再指定泛型类型:
// 筛选带selector参数的Sum方法定义,再实例化为Srtd类型的泛型方法
var sumMethodDefinition = typeof(System.Linq.Enumerable).GetMethods()
    .Where(m => m.Name == "Sum" && m.GetParameters().Length == 2)
    .First()
    .MakeGenericMethod(typeof(Srtd));
  1. 生成正确的Sum调用表达式
    扩展方法的调用逻辑中,第一个参数是源集合(propertyExp即s.Srt.Srtd),第二个参数是selector的Lambda表达式:
var exp2 = Expression.Call(sumMethodDefinition, propertyExp, selectorLambda);

完整修正代码

ParameterExpression argParam = Expression.Parameter(typeof(T), "s");

var property1 = typeof(T).GetProperty(nameof(Srt));
var property2 = property1.PropertyType.GetProperty(nameof(Srt.Srtd)); // 修正语法:使用nameof获取属性名
var propertyExp1 = Expression.Property(argParam, property1);
var propertyExp = Expression.Property(propertyExp1, property2);

ParameterExpression argX = Expression.Parameter(typeof(Srtd), "x");
var prt1 = typeof(Srtd).GetProperty(nameof(Srtd.Elt));
var prtExp = Expression.Property(argX, prt1);
var selectorLambda = Expression.Lambda<Func<Srtd, decimal?>>(prtExp, argX);

var sumMethodDefinition = typeof(System.Linq.Enumerable).GetMethods()
    .Where(m => m.Name == "Sum" && m.GetParameters().Length == 2)
    .First()
    .MakeGenericMethod(typeof(Srtd));

var exp2 = Expression.Call(sumMethodDefinition, propertyExp, selectorLambda);

执行以上代码后,就能生成你需要的s.Srt.Srtd.Sum(x=>x.Elt)表达式树。

内容的提问来源于stack exchange,提问作者Rushi Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:15:27