动态获取 Func的结果调用

发布于 2024-08-05 05:10:01 字数 1068 浏览 3 评论 0原文

我正在尝试根据满足特定标准来序列化某些内容。

为此,我最初的希望是在对象的属性上使用包含 lambda 表达式的属性。

然而,由于这是不可能完成的,我已经决定使用 Func。类中的成员并通过 property 属性传递此 Func 的类型(或第一个参数类型)和名称。例如:

Func<SomeObject, bool> func = (p => p.Value == 4);
[FuncAtt(typeof(SomeObject), "func")]
public SomeObject PropertyName { get; set;}

在我的序列化器中,我需要调用此 Func

假设我有一个类型 t,在本例中它等于 typeof(SomeObject),或更抽象地等于 typeof(T)。我还可以获得 Func本身,但只能通过作为对象的反射来实现。

我天真的做法是这样的:

object func = typeof(MyClass).GetField(attribute.FuncName).GetValue(MyClassInstance);
Type funcType = typeof(Func<,>).MakeGenericType(attribute.Type, typeof(bool));

ParameterExpression p = Expression.Parameter(attribute.Type, objectToSerialize);
LambdaExpression l = Expression.Lambda(funcType, func, p); /* Won't work */

但这会导致将 lambda 转换为委托的问题,这显然是错误的。

我尝试用这个代替“func”:

(Expression)((Action)(() => func))

但这依赖于 func 是方法调用而不是 lambda。

那么,有人能指出我正确的方向吗?

I am trying to serialize something based upon meeting particular criteria.

To this end my original hope was to use attributes containing a lambda expression on an object's properties.

However, as this cannot be done I've settled for having a Func<T,bool> member within the class and passing the type (or first parameter type) and name of this Func through the property attribute. E.g.:

Func<SomeObject, bool> func = (p => p.Value == 4);
[FuncAtt(typeof(SomeObject), "func")]
public SomeObject PropertyName { get; set;}

In my serializer I need to call this Func<T, bool>.

Let's assume I have a Type t which is equal to typeof(SomeObject) in this case, or more abstractly, typeof(T). I can also get the Func<T,bool> itself, but only through reflection as an object.

My naive approach is something along these lines:

object func = typeof(MyClass).GetField(attribute.FuncName).GetValue(MyClassInstance);
Type funcType = typeof(Func<,>).MakeGenericType(attribute.Type, typeof(bool));

ParameterExpression p = Expression.Parameter(attribute.Type, objectToSerialize);
LambdaExpression l = Expression.Lambda(funcType, func, p); /* Won't work */

But this leads to the problem of casting a lambda to a delegate which is apparently erroneous.

I tried this in place of 'func':

(Expression)((Action)(() => func))

But that relies on func being a method call not a lambda.

So, can anyone point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只等公子 2024-08-12 05:10:01

您可以执行类似的操作,无需表达式:

public static class Test
{
    public static Predicate<int> func = s => s > 20;
}

并获取值:

    private void Form1_Load(object sender, EventArgs e)
    {
        var a = typeof(Test).GetField("func");

        bool validates = ((Predicate<int>)a.GetValue(null)).Invoke(100);
    }

编辑以在不知道类型的情况下获取值:

bool validates = (bool)((Delegate)a.GetValue(null)).DynamicInvoke(100);

You can just do something like this, without need for expressions:

public static class Test
{
    public static Predicate<int> func = s => s > 20;
}

and to get the value:

    private void Form1_Load(object sender, EventArgs e)
    {
        var a = typeof(Test).GetField("func");

        bool validates = ((Predicate<int>)a.GetValue(null)).Invoke(100);
    }

edit to get the value without knowing the type:

bool validates = (bool)((Delegate)a.GetValue(null)).DynamicInvoke(100);
画尸师 2024-08-12 05:10:01

我认为您可以使用 lambda 表达式的 Compile 方法将其转换为委托。

这是我在 MSDN 上找到的:

表达式<(Of <(TDelegate>)>)
type 提供了 Compile 方法,
编译由以下表示的代码
将表达式树转换为可执行文件
代表。这段可执行代码是
相当于可执行代码
如果有的话就会产生
lambda 表达式被分配给 a
原本是委托类型。

在这里您可以找到它。

I think you can use Compile method of a lambda expression to cast it to a delegate.

here's what I found on MSDN:

The Expression<(Of <(TDelegate>)>)
type provides the Compile method,
that compiles the code represented by
the expression tree into an executable
delegate. This executable code is
equivalent to the executable code that
would have been generated had the
lambda expression been assigned to a
delegate type originally.

Here you can find it.

划一舟意中人 2024-08-12 05:10:01

不确定这是否有效,但就是这样:

// not sure what are you doing in this line, but assume it should return
// a method name specified in the attribute, e.g. "func" in your example.
// Also "func" must be a method (static one in my example) of SomeObject class
String funcname = typeof(MyClass).GetField(attribute.FuncName).GetValue(MyClassInstance);
ParameterExpression param = Expression.Parameter(typeof(SomeObject), "p");
MethodCallExpression call = Expression.Call(SomeObject, funcname, new Type[] { typeof(SomeObject), typeof(Boolean) }, param);
LambdaExpression lambda = Expression.Lambda<Func<SomeObject, Boolean>>(call, param);

现在您可以像这样调用“func”方法:

Boolean result = lambda.Compile()(SomeObjectInstance);

Not sure this is working sample, but this is the way:

// not sure what are you doing in this line, but assume it should return
// a method name specified in the attribute, e.g. "func" in your example.
// Also "func" must be a method (static one in my example) of SomeObject class
String funcname = typeof(MyClass).GetField(attribute.FuncName).GetValue(MyClassInstance);
ParameterExpression param = Expression.Parameter(typeof(SomeObject), "p");
MethodCallExpression call = Expression.Call(SomeObject, funcname, new Type[] { typeof(SomeObject), typeof(Boolean) }, param);
LambdaExpression lambda = Expression.Lambda<Func<SomeObject, Boolean>>(call, param);

now you can call the "func" method like this:

Boolean result = lambda.Compile()(SomeObjectInstance);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文