gpt4 book ai didi

c# - 构造 .NET 表达式以调用动态对象的正确方法

转载 作者:太空狗 更新时间:2023-10-29 23:51:11 24 4
gpt4 key购买 nike

我需要创建一个调用动态对象的 System.Linq.Expressions.Expression。动态对象可以是 ExpandoObject 或任何其他 IDynamicMetaObjectProvider

考虑以下测试:

var myInstance = DateTime.Now;

var methodInfo = myInstance.GetType().GetMethod("ToUniversalTime");

var methodCallExpression = Expression.Call(Expression.Constant(myInstance), methodInfo);
var expression = Expression.Lambda(methodCallExpression);

Assert.AreEqual(myInstance.ToUniversalTime(), expression.Compile().DynamicInvoke());

我需要在声明 myInstance 时创建一个等效表达式(仅作为示例):

dynamic myInstance = new ExpandoObject();
myInstance.MyMethod = new Func<string>(() => "hello world");

我想我需要使用 Expression.Dynamic 方法(参见 MSDN )。但我不知道如何使用它。我试图在谷歌上搜索,但我找到的唯一示例使用无法正式使用的 Microsoft.CSharp.RuntimeBinder.Binder 类(请参阅 MSDN):

This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.

使用 Microsoft.CSharp.RuntimeBinder.Binder 我可以编写以下代码:

dynamic myInstance = new ExpandoObject();
myInstance.MyMethod = new Func<string>(() => "hello world");

var binder = Binder.InvokeMember(
CSharpBinderFlags.None,
"MyMethod",
null,
this.GetType(),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant, null) });

var methodCallExpression = Expression.Dynamic(binder, typeof(object), Expression.Constant(myInstance));
var expression = Expression.Lambda(methodCallExpression);

Assert.AreEqual(myInstance.MyMethod(), expression.Compile().DynamicInvoke());

这个解决方案正确吗?

最佳答案

这里有一个问题:根据我的理解,在没有某种 Binder 对象的情况下进行动态调用是没有意义的。

Binder 对象表示动态名称解析所遵循的规则:

  • 匹配是否应该区分大小写?
  • 应该如何解决方法重载问题?
  • 如果对象是非动态对象怎么办?
  • 您使用什么后备方案?

换句话说,Binder对象代表调用“语言”的语义,而IDynamicMetaObjectProvider代表被调用对象的语义。

所以,是的,我们不应该使用 CSharp Binder 对象。尤其是当发生某些只能通过使用对象的内部结构来解决的问题时,这种感觉尤其明显。然而,另一种方法是简单地使用另一个非框架提供的 Binder 实现。

关于c# - 构造 .NET 表达式以调用动态对象的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23175214/

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