C# – Dynamically get the result of a Func invocation

cdynamicgenericslambdareflection

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?

Best Answer

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