Mrinal Kamboj
Mrinal Kamboj

Reputation: 11478

Accessing Type T property in the ParameterExpression type Dictionary<string,T>

I have expression tree code used for data filtering, till date it was used on a Generic list List<T> and following code use to work fine:

var parameterType = Expression.Parameter(typeof(T), "obj");
var memberExpression = Expression.Property(parameterType, "Name");

It was easy to create a binary expression as follows and process the result:

var constantExpression = Expression.Constant("Jack",typeof(string));

var finalExpression = Expression.Equal(memberExpression,constantExpression);

var resultFunc = Expression.Lambda<Func<T, bool>>(finalExpression, parameterType).Compile();

// Final Result
sourceList.Where(obj => resultFunc(obj));

Here Name is a property in Type T, as result post Lambda compilation was Func<T,bool>, I use to apply the same to the Where clause of IEnumerable type. Now the underlying system has changed to use the same code on Dictionary<string,T>, so all the Type T values in the collection now have a string Key associated and type T is now accessible as a value of dictionary object. Also I am applying on a IQueryable, which takes an expression tree the final lambda post compilation at source would be Func<KeyValuePair<string,T>,bool>, therefore cannot apply the Value in the final result processing.

Following is the code modification now:

var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");

Following code fails, since now Name property is in Value of the KeyValuePair and we cannot use it as Type T:

var memberExpression = Expression.Property(parameterType, "Name");

Any pointer to make it work or any suggestion to set me in the right direction?

Upvotes: 1

Views: 1020

Answers (1)

Maksim Simkin
Maksim Simkin

Reputation: 9679

You could get Expression for calling ["name"] item this way:

var nameProperty= Expression.Call(parameterType, 
       typeof(IDictionary<string, T>).GetMethod("get_Item"), 
       Expression.Constant("Name")); 

or as:

var nameProperty = Expression.Property(parameterType, "Item", 
                         new Expression[] { Expression.Constant("Name") });

Both is call of Item property

EDIT : To get Value from KeyValuePair you have to get property Key, compare it with "Name" and a property Value and compare it with value:

var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");

var value = Expression.Property(parameterType, "Value" );
var key = Expression.Property(parameterType, "Key");

var  eq1 = Expression.Equal(key, Expression.Constant("Name"));
var  eq2 = Expression.Equal(value, constantExpression);
var and = Expression.And(eq1, eq2);
var lambda = Expression.Lambda(and, parameterType);

Upvotes: 1

Related Questions