Expression-Tree for array property

arrays c# expression-trees

Question

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?

Popular Answer

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 });


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why