Reputation: 352
I am trying to dynamically generate binary expressions using Expression.MakeBinary:
public static BinaryExpression MakeBinary(
ExpressionType binaryType,
Expression left,
Expression right
)
A simple example of that for Property "Bar" of class "Foo" would be:
var param = Expression.Parameter(typeof(Foo));
var left = MemberExpression.Property(param, "Bar");
var propertyType = typeof(Foo).GetProperty("Bar").PropertyType;
var right = Expression.Constant(Convert.ChangeType("newValue", propertyType ));
var expression = Expression.MakeBinary(ExpressionType.Equal, left, right);
My goal is to be able to do the same thing as above, but instead of comparing "Bar" property with "newValue", in my case "Bar" is a dictionary and I want to compare a specific entry of that dictionary with "newValue". What I want to achieve would look like this (but this code is not valid):
var param = Expression.Parameter(typeof(Foo));
var left = MemberExpression.Property(param, "Bar[\"entryName\"]");
I would suppose what I am trying to do is possible, but I can't seem to find the right syntax/class/method to use. Obviously the code above returns an error, since Bar["entryName"] is not a property. But how can I build the expression based on a specific entry in a dictionary for a given Type?
The high level application of this is to be able to apply rules, using field/operator/compareValue as parameters, but being able to indicate the "path" to that field (depending on the class, sometimes it would be a plain property, or as asked here, an entry in a dictionary, etc.).
Thank you
Upvotes: 4
Views: 1033
Reputation: 43916
You can use Expression.MakeIndex()
:
var param = Expression.Parameter(typeof(Foo));
var bar = MemberExpression.Property(param, "Bar");
Type dictionaryType = typeof(Foo).GetProperty("Bar").PropertyType;
PropertyInfo indexerProp = dictionaryType.GetProperty("Item");
var dictKeyConstant = Expression.Constant("entryName");
var dictAccess = Expression.MakeIndex(bar, indexerProp, new[] {dictKeyConstant});
var propertyType = indexerProp.PropertyType;
var right = Expression.Constant(Convert.ChangeType("newValue", propertyType ));
var expression = Expression.MakeBinary(ExpressionType.Equal, dictAccess, right);
The property name of an indexer is always "Item". The dictKeyConstant
should be the expression for your dictionary's key.
Upvotes: 4