Suppose we have this class
class ClassA
{
public ClassB[] MyProperty { get; set; }
}
class ClassB
{
public int[] AnotherProperty { get; set; }
}
Now I want to access the value for AnotherProperty
for a given instance of ClassA
and an array of indexes that reflect the two arrays So { 3 , 5 }
e.g. means the fourth element within the top-level (evaluates to MyProperty
) and the sixth element within second level (AnotherProperty
). Thus I´m going to create a Func<ClassA, int[], int>
by the means of an expression-tree:
var instanceArgument = Expression.Parameter(typeof(MyClass), "x");
var indexesArgument = Expression.Parameter(typeof(int[]), "i");
var expr = instanceArgument;
expr = Expression.Property(expr, "MyProperty");
expr = Expression.ArrayIndex(expr, ???);
expr = Expression.Property(expr, "AnotherProperty");
expr = Expression.ArrayIndex(expr, ???);
var f = Expression.Lambda<Func<ClassA, int[], int>>(expr, instanceArgument, indexesArgument);
As you can see I´m unsure on how to provide the indexes to the expression. I know I have to use the indexesArgument
which reflects the indexes passed to our delegate, but how to access the values 3
and 5
?
We need a further ArrayIndexExpression
to access the i-th element within our indexes
-argument:
expr = Expression.Property(expr, "MyProperty");
expr = Expression.ArrayIndex(expr, Expression.ArrayIndex(indexesArgument, Exression.Constant(0));
expr = Expression.Property(expr, "AnotherProperty");
expr = Expression.ArrayIndex(expr, Expression.ArrayExpression(indexesArgument, Expression.Constant(1));
The Expression.Constant(0)
leads to an ArrayIndexExpression
of the first element within indexes
, Expression.Constant(1)
to the second one accordingly.
Now after having compiled the expression-tree we can call the delegate to access the second int-value for AnotherProperty
of the first instance within MyProperty
:
ClassA a = new ClassA
{
MyProperty = new[] { new ClassB
{
AnotherProperty = new[] { 1, 4 }
}
};
int result = f(x, new[] { 0, 1 });