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

如何通过C#表达式树为Person类的Contacts集合属性赋值?

问题分析与解决方案

哦,我一眼就看到你出错的地方了——你找错了Add方法的所属类型!你的Person.Contacts是List<Contact>类型,但你却去获取List<Person>的Add方法,类型完全不匹配,这肯定会触发异常。

下面给你两种正确的实现方式,用表达式树把那些MemberInitExpression形式的Contact实例填充到Person的Contacts属性里:

方式一:用ListInit直接初始化集合(更简洁)

这种方式利用表达式树的ListInit特性,直接创建List<Contact>并批量添加元素,代码更紧凑:

// 假设你的MemberInitExpression集合是:IEnumerable<MemberInitExpression> contactInits
var listAddMethod = typeof(List<Contact>).GetMethod("Add", new[] { typeof(Contact) });

// 1. 创建List<Contact>的初始化表达式,批量添加所有Contact实例
var contactsListInit = Expression.ListInit(
    Expression.New(typeof(List<Contact>)),
    contactInits.Select(contactInit => 
        Expression.ElementInit(listAddMethod, contactInit)
    )
);

// 2. 创建Person实例并赋值Contacts属性
var personInitExpr = Expression.MemberInit(
    Expression.New(typeof(Person)),
    Expression.Bind(
        typeof(Person).GetProperty(nameof(Person.Contacts)),
        contactsListInit
    )
);

// 3. 编译成委托并执行
var createPerson = Expression.Lambda<Func<Person>>(personInitExpr).Compile();
Person resultPerson = createPerson();

方式二:用Block表达式分步操作(更直观)

如果你想更清晰地看到每一步的逻辑,可以用Block表达式分步创建列表、添加元素、赋值给Person:

// 假设你的MemberInitExpression集合是:IEnumerable<MemberInitExpression> contactInits
var listAddMethod = typeof(List<Contact>).GetMethod("Add", new[] { typeof(Contact) });

// 1. 定义一个变量来存储Contacts列表
var listVar = Expression.Variable(typeof(List<Contact>), "contactsList");

// 2. 创建列表实例并赋值给变量
var assignList = Expression.Assign(listVar, Expression.New(typeof(List<Contact>)));

// 3. 生成所有Add元素的表达式
var addContactExprs = contactInits.Select(contactInit => 
    Expression.Call(listVar, listAddMethod, contactInit)
);

// 4. 创建Person实例并将列表赋值给Contacts属性
var personExpr = Expression.MemberInit(
    Expression.New(typeof(Person)),
    Expression.Bind(typeof(Person).GetProperty(nameof(Person.Contacts)), listVar)
);

// 5. 组合所有步骤成Block表达式
var blockExpr = Expression.Block(
    new[] { listVar },
    assignList,
    Expression.AddRange(addContactExprs),
    personExpr
);

// 6. 编译执行
var createPerson = Expression.Lambda<Func<Person>>(blockExpr).Compile();
Person resultPerson = createPerson();

关键修正点

你之前的代码错误在于:

// 错误:拿了List<Person>的Add方法,和Contacts的List<Contact>类型不匹配
var method = typeof(List<Person>).GetMethods().Where(m => m.Name == "Add").First().MakeGenericMethod(typeof(Person));

正确的做法是获取List<Contact>的Add方法,而且不需要调用MakeGenericMethod——因为List<Contact>已经是具体的泛型类型,它的Add方法参数就是Contact,直接获取即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:45:06