gpt4 book ai didi

c# - 具有动态参数的表达式树

转载 作者:太空狗 更新时间:2023-10-29 19:42:32 27 4
gpt4 key购买 nike

我想转换这个:

Func<dynamic, object> myFunc = t => return t.Name + " " + t.Surname;

进入表达式树。

我想出的是:

ParameterExpression target = ExpressionParameter(typeof(dynamic), "target");
ParameterExpression result = ExpressionParameter(typeof(object), "result");
BlockExpression block = Expression.Block(
new [] { result },
Expression.Assign(
result,
Expression.Add(
Expression.Add(
Expression.Property(target, "Name"),
Expression.Constant(" ", typeof(string))
),
Expression.Property(target, "Surname")
)
)
);
Func<dynamic, object> myFunc = Expression.Lambda<dynamic, object>>(block, target).Compile();

然而,编译器不喜欢typeof(dynamic) ,我有点明白了。 dynamic不是类型,它是 object本质上。

所以我开始更改 ParameterExpression :

ParameterExpression target = ExpressionParameter(typeof(object), "target");

代码现在可以编译,但在运行时出现问题。

我正在尝试获取属性值 Nametarget ,如果对象是 dynamic,这可能有意义.

但是自target被认为是 object 类型,表达式抛出错误告诉我 Name不作为属性存在。

是否有用于获取动态属性的表达式?

最佳答案

对于那些对解决方案感兴趣或曾经对解决方案感兴趣的人:

ParameterExpression target = Expression.Parameter(typeof(object), "target");
ParameterExpression result = Expression.Parameter(typeof(object), "result");

CallSiteBinder getName = Binder.GetMember(
CSharpBinderFlags.None, "Name", typeof(Program),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}
);

CallSiteBinder getSurname= Binder.GetMember(
CSharpBinderFlags.None, "Surname", typeof(Program),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}
);

BlockExpression block = Expression.Block(
new[] { result },
Expression.Assign(
result,
Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(object[]) }),
Expression.NewArrayInit(typeof(object),
Expression.Dynamic(getName, typeof(object), target),
Expression.Constant(" ", typeof(object)),
Expression.Dynamic(getSurname, typeof(object), target)
)
)
)
);

Func<dynamic, object> myFunc = Expression.Lambda<Func<dynamic, object>>(block, target).Compile();

这正是我正在做的:

  1. 创建了一个 CallSiteBinder,它获取作为参数传递的动态对象的动态属性 Name 的值
  2. 创建了一个 CallSiteBinder,它获取作为参数传递的动态对象的动态属性 Surname 的值
  3. 调用了方法string.Concat(params object[] args)。为此,我需要将参数作为 object 数组发送。我正在使用 getName""getSurname 的值创建数组。

我使用以下答案作为指导和引用:

C# 4 “dynamic” in expression trees

通过上述方法,可以做这样的事情:

dynamic person = new ExpandoObject();
person.Name = "Matt";
person.Surname = "Smith";

object value = myFunc(person);
Console.WriteLine(value); //Will print out "Matt Smith"

//Internally it just calls:
//string.Concat(new object[] { person.Name, " ", person.Surname });

关于c# - 具有动态参数的表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29944137/

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