具有动态参数的表达式树
Expression Trees with dynamic parameter
我要转换为:
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");
代码现在可以编译,但在运行时出现问题。
我正在尝试获取 target
的 属性 Name
的值,如果对象是 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();
这正是我正在做的事情:
- 创建了一个
CallSiteBinder
获取作为参数传递的动态对象的动态值 属性 Name
- 创建了一个
CallSiteBinder
获取作为参数传递的动态对象的动态值 属性 Surname
- 调用了方法
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 });
我要转换为:
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");
代码现在可以编译,但在运行时出现问题。
我正在尝试获取 target
的 属性 Name
的值,如果对象是 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();
这正是我正在做的事情:
- 创建了一个
CallSiteBinder
获取作为参数传递的动态对象的动态值 属性Name
- 创建了一个
CallSiteBinder
获取作为参数传递的动态对象的动态值 属性Surname
- 调用了方法
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 });