简体   繁体   中英

Generic method with inferred generic arguments

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

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...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM