gpt4 book ai didi

c#-4.0 - 如何获取静态(编译时)类型的 IDynamicMetaObjectProvider?

转载 作者:行者123 更新时间:2023-12-03 06:25:42 26 4
gpt4 key购买 nike

我想在编译时类型的上下文/范围中执行动态表达式(由用户提供)。在下面的示例中,上下文是任意编译时类型的实例。为了创建评估范围,我想利用所有可用属性及其类型在编译时已知的事实。

var engine = IronPython.Hosting.Python.CreateEngine();
var func = engine.CreateScriptSourceFromString("a + b").Compile();
var context = new { a = 1, b = 2 };
var scope = engine.CreateScope((IDynamicMetaObjectProvider)context); // Fails to compile
var result = func.Execute(scope);
context.a = 5;
var result2 = func.Execute(scope);

我不想采取的解决方案是:

  1. 让上下文继承 DynamicObject 并覆盖 GetMember(出于性能原因)
  2. 将上下文添加到作用域并将表达式更改为“context.a + context.b”(出于可用性原因)

我确定,已经有一种获取 IDynamicMetaObjectProvider 的机制,但无法弄清楚。

最佳答案

DLR 自动知道如何动态调用在编译时定义的成员。事实上,即使您有 IDynamicMetaObjectProvider 的实际实现,它也会在尝试动态元对象之前首先查找静态定义的成员。

首先,您不需要(也不能)将普通旧 clr 对象 转换为 IDynamicMetaObjectProvider(如果它实际上并未实现)。

其次,我认为您对 python 范围看不到对象成员的困惑来自于您使用匿名类型这一事实。 匿名类型被标记为内部,因此你的Python作用域无权查看它的成员,并提示它没有实现它。使用实际定义的对象或 ExpandoObjectExpandoObjects 实际上在获取成员(但不设置它们)方面具有非常出色的性能,事实上,它们比普通的旧 clr 对象更好获取成员性能由DLR访问。

以下基准测试显示 ExpandoObject getter 的运行速度比 DLR 调用的 poco 快约 43%:

public class Poco{
public int One {get;set;}
public string Test {get;set;}
}

void Main()
{
var iterations =Math.Pow(10,8);

dynamic expando = new ExpandoObject();
expando.One =1;
expando.Test = "Test";
dynamic poco = new Poco{One =1, Test = "Test"};

var stopWatch = new Stopwatch();
stopWatch.Start();
for(int i=0; i < iterations; i++){
var test1 = poco.One;
var test2 = poco.Test;
}
stopWatch.Stop();
var dlrPocoTime = stopWatch.ElapsedMilliseconds;

stopWatch = new Stopwatch();
stopWatch.Start();
for(int i=0; i < iterations; i++){
var test1 = expando.One;
var test2 = expando.Test;
}
stopWatch.Stop();
var expandoTime = stopWatch.ElapsedMilliseconds;


Console.WriteLine((double)dlrPocoTime/expandoTime);

}

关于c#-4.0 - 如何获取静态(编译时)类型的 IDynamicMetaObjectProvider?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11837126/

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