gpt4 book ai didi

c# - 表达式树 : avoid DynamicInvoke

转载 作者:行者123 更新时间:2023-11-30 17:08:20 26 4
gpt4 key购买 nike

我在运行时使用表达式树构建委托(delegate):

Type type = GetType();
ParameterExpression parameterType = Expression.Parameter(type);
...
Delegate delegate = Expression.Lambda(*something*, parameterType).Compile();

我在编译时不知道方法 GetType() 返回的类型。是否可以在不使用昂贵的 DynamicInvoke() 方法的情况下调用我的委托(delegate)?

编辑:

在我的应用程序中,我有一个基本抽象类:

public abstract class Frame
{
public string RawContent { get; set; }

// ...
}

应用程序在运行时会使用一些继承Frame的对象;这些对象的类型在编译时是未知的,因为它们将与 MEF(插件)一起加载。应用程序的目标是过滤具有错误数据的对象:例如,如果程序必须处理像这样的类的某些对象:

public class Frame01 : Frame
{
public int Counter6hours { get; set; }

public int DeltaCounter6hours { get; set; }
}

我希望我的用户能够在应用程序的配置文件中编写如下内容:

<filtersSection>
<filters>
<filter class="Frame01" expression="Counter6hours < 0" />
<filter class="Frame01" expression="DeltaCounter6hours > 2500" />
</filters>
<filtersSection>

我设法创建了一个表达式树并将其编译为每个过滤器的委托(delegate)。但我不能将它转换为 Func,因为我在编译时不知道 Frame01 类型......所以,目前,我使用我的委托(delegate)的方法 DynamicInvoke()底层方法。该应用程序将不得不处理大量对象,我担心性能问题...因此,在这个示例中,我尝试以编程方式构建 Func 对象,但我不确定这是否可行。

PS:对不起,我的英语不好......

最佳答案

我仍然不完全清楚这就是你想要的,但我认为你所需要的只是一个转换:你的表达式将有一个 Frame 类型的参数,将其转换为 Frame01 然后在上面运行你的过滤器。

在代码中:

var type = typeof(Frame01);

var param = Expression.Parameter(typeof(Frame));
var casted = Expression.Convert(param, type);

// this part will be dynamic in your actual code
var condition = Expression.LessThan(
Expression.Property(casted, "Counter6hours"), Expression.Constant(0));

var result = Expression.Lambda<Func<Frame, bool>>(condition, param)
.Compile();

这样,下面的测试就通过了:

Assert.IsTrue(result(new Frame01 { Counter6hours = -1 }));
Assert.IsFalse(result(new Frame01 { Counter6hours = 1 }));
Assert.Throws<InvalidCastException>(() => result(new Frame02()));

关于c# - 表达式树 : avoid DynamicInvoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13817666/

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