tags:

views:

240

answers:

2

I have the following code to create an expression of a func for accessing a property of a class

public static Expression<Func<TObj, TProperty>> BuildGet<TObj, TProperty>(PropertyInfo property)
{
    Type type = typeof(TObj);
    ParameterExpression arg = Expression.Parameter(type, "x");
    var prop = Expression.Property(arg, property);

    return Expression.Lambda<Func<TObj, TProperty>>(prop, arg);
}

The problem is, is that I have to pass in TObj and TProperty even though they are known (properties on PropertyInfo class - .DeclaringType and .PropertyType).

Is there a way around this so I don't explicitly have to pass them in?

The return type must remain as Expression<Func<TObj, TProperty>>

+1  A: 

How is the compiler supposed to infer the type of TObj? You are not passing any argument to the function that is of that type.

You could try something like this:

public static Expression<Func<TObj, TProperty>> BuildGet<TObj, TProperty>
    (TObj obj, TProperty property) { ... }

which would allow the compiler to infer the types of TObj and TProperty but that would mean you would have to refactor your method as you are using the PropertyInfo parameter currently.

Andrew Hare
yeah I know that's the problem, I'm looking for a solution :) I take it that means there isn't one :(
Andrew Bullock
You can't pass TProperty, it requires that you have an instance.
Stefan Steinegger
+2  A: 

If the return type has to remain Func<TObj, TProperty> then the method has to stay generic. You will have to specify the types at compile-time. That's the thing - although PropertyInfo knows the types, that information is only available at execution time, whereas the compiler needs to know the type information in order to check that you're using the value properly, etc. It can't possibly know what the execution-time values of the properties will be.

If you could change the return type to just Expression then you could create an Expression<Func<TObj, TProperty>> with the appropriate types at execution time, but just return it as an Expression. You wouldn't be able to use the return value in a compile-time type-safe way without casting, but it may be helpful...

Jon Skeet
Yeah i think thats my only alternative. Can't decide whether id rather cast an Expression or pass in the Ts hmmmm. Thanks :)
Andrew Bullock