gpt4 book ai didi

c# - 不使用 MemberInit 创建实例和设置成员的表达式

转载 作者:太空宇宙 更新时间:2023-11-03 22:47:16 25 4
gpt4 key购买 nike

我需要创建一个实例并设置一些属性。通常我会使用 Expression.MemberInit(Expression.New(type), memberBindings),但我需要通过调用自定义方法来创建实例。我不知道如何在实例表达式上设置成员。

我正在创建这样的实例。我实际上并没有使用 Activator.CreateInstance,但它应该适用于此示例。

var method = typeof( Activator ).GetMethod( nameof( Activator.CreateInstance ), new Type[] { typeof( Type ) } );
Expression expression = Expression.Call( method, Expression.Constant( typeof( TestClass ) ) );

创建实例的表达式后,如何设置对象成员?

最佳答案

可以用 Expression.Block 创建这样的表达式,但请注意,它只能用于编译 lambda 委托(delegate),因为 C# 编译器和查询提供程序不支持表达式 block ,LINQ to Objects 除外。

首先确保创建实例方法返回正确的类型:

var method = typeof(Activator).GetMethod(nameof(Activator.CreateInstance), new Type[] { typeof(Type) });
var newObj = Expression.Convert(Expression.Call(method, Expression.Constant(typeof(TestClass))), typeof(TestClass));

并假设您已经有了一个通常与 Expression.MemberInit 一起使用的 MemberAssignment 表达式列表:

IEnumerable<MemberAssignment> memberBindings = ...;

然后可以按如下方式构建所讨论的表达式:

var obj = Expression.Variable(newObj.Type, "obj");
var expressions = new List<Expression>();
expressions.Add(Expression.Assign(obj, newObj));
expressions.AddRange(memberBindings.Select(b => Expression.Assign(
Expression.MakeMemberAccess(obj, b.Member), b.Expression)));
expressions.Add(obj);
var variables = new Expression[] { obj };
var result = Expression.Block(variables, expressions);

所以我们创建了一个名为obj的变量,赋值对象创建方法的结果,然后为每个成员绑定(bind)生成成员赋值,最后返回obj( block 表达式列表中的最后一个表达式)。

关于c# - 不使用 MemberInit 创建实例和设置成员的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49293230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com