代码之家  ›  专栏  ›  技术社区  ›  Matt Mitchell

动态获取func<t,bool>调用的结果

  •  2
  • Matt Mitchell  · 技术社区  · 15 年前

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

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

    但是,由于无法做到这一点,我已经决定在类中拥有func<t、bool>成员,并通过属性属性传递此func的类型(或第一个参数类型)和名称。例如。:

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

    在我的序列化程序中,我需要调用这个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 */
    

    但这导致了将lambda强制转换为明显错误的委托的问题。

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

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

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

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

    3 回复  |  直到 15 年前
        1
  •  4
  •   Jan Jongboom    15 年前

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

    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);
    
        2
  •  1
  •   Beatles1692    15 年前

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

    以下是我在msdn上找到的:

    表达式<(of<(tDelegate>)>) 类型提供编译方法, 它编译由 表达式树转换为可执行文件 代表。此可执行代码是 相当于可执行代码 如果 lambda表达式已分配给 最初的委托类型。

    Here 你可以找到它。

        3
  •  1
  •   Kamarey    15 年前

    不确定这是工作样本,但这是方法:

    // 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);