动态获取 Func<T,bool> 调用的结果

Mat*_*ell 3 c# generics reflection lambda dynamic

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

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

但是,由于这是无法完成的,我决定在类中使用 Func<T,bool> 成员,并通过 property 属性传递此 Func 的类型(或第一个参数类型)和名称。例如:

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

在我的序列化器中,我需要调用此 Func<T, bool>。

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

我天真的做法是这样的:

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 */
Run Code Online (Sandbox Code Playgroud)

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

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

(Expression)((Action)(() => func))
Run Code Online (Sandbox Code Playgroud)

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

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

Jan*_*oom 5

你可以这样做,不需要表达式:

public static class Test
{
    public static Predicate<int> func = s => s > 20;
}
Run Code Online (Sandbox Code Playgroud)

并获取值:

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

        bool validates = ((Predicate<int>)a.GetValue(null)).Invoke(100);
    }
Run Code Online (Sandbox Code Playgroud)

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

bool validates = (bool)((Delegate)a.GetValue(null)).DynamicInvoke(100);
Run Code Online (Sandbox Code Playgroud)