Vishal
Vishal

Reputation: 12369

How to dynamically use the PropertyType reflection attribute to create a respective typed Function<>?

I want to use type returned by PropertyType to create a typed function. I found this similiar using type returned by Type.GetType() in c# but this mentions how to create a list but does not mention how we can create a Func<>. Please help me out.

Pseudocode:

PropertyInfo inf = typeof(SomeClass).GetProperty("PropertyName");
Type T=inf.PropertyType;
Expression<Func<SomeClass,T>> le = GetPropertyOrFieldByName<SomeClass,T>("PropertyName");

static Expression<Func<TSource, TResult>> GetPropertyOrFieldByName<TSource,TResult>(string propertyOrFieldName)
{ 
ParameterExpression item = Expression.Parameter(typeof(TSource), "expr");MemberExpression prop = LambdaExpression.PropertyOrField(item, propertyOrFieldName);
var expr = Expression.Lambda<Func<TSource, TResult>>(prop, new ParameterExpression[] { item });
expr.Compile();
return expr;
}

Upvotes: 1

Views: 391

Answers (4)

Jon Skeet
Jon Skeet

Reputation: 1500525

You can create the expression tree, but you can't declare its type in the code. Where you've got this:

Expression<Func<SomeClass,T>> le = ...

T has to be known at compile time (or be a type parameter). Instead, your T is a variable whose value is only known at execution time.

Now, the next question is whether you really need that anyway - or in what way you need it. What are you trying to do with the expression? Could you just use the nongeneric Expression class instead as the variable type?

If you genuinely want an expression tree, you don't need to worry about MakeGenericType etc - use the Expression.Property method.

Upvotes: 1

Steven
Steven

Reputation: 172646

If you want to call the GetPropertyOrFieldByName with the PropertyType, this should work:

PropertyInfo inf = typeof(SomeClass).GetProperty("PropertyName");
Type T = inf.PropertyType;

object le =
    typeof([TypeThatDeclaresMethod]).GetMethod("GetPropertyOrFieldByName")
    .MakeGenericMethod(typeof(SomeClass), T)
    .Invoke(null, new object[] { "PropertyName" });

Assuming that the GetPropertyOrFieldByName method is a public static method.

Upvotes: 1

mfeingold
mfeingold

Reputation: 7154

Type parameter = ...;
Type result = ...;
Type your_type = typeof(Func<,>).MakeGenericType(new Type[] {parameter, result});

Upvotes: 1

Eric Mickelsen
Eric Mickelsen

Reputation: 10377

Simply use MakeGenericType(new Type[] { SomeClass, T }).

EDIT More detail:

Type T2 = typeof(Excpression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(new Type[] { SomeClass, T }));
... Activator.CreateInstance(T2);

,

Upvotes: 1

Related Questions