假設我們有這門課
class ClassA
{
public ClassB[] MyProperty { get; set; }
}
class ClassB
{
public int[] AnotherProperty { get; set; }
}
現在我想為ClassA
的給定實例和反映兩個數組的索引數組訪問AnotherProperty
的值So { 3 , 5 }
例如意味著頂層中的第四個元素(評估為MyProperty
)和第六個元素在第二級( AnotherProperty
)。因此,我將通過表達式樹創建一個Func<ClassA, int[], int>
:
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);
正如您所看到的,我不確定如何為表達式提供索引。我知道我必須使用indexesArgument
來反映傳遞給我們的委託的索引,但是如何訪問值3
和5
?
我們還需要一個ArrayIndexExpression
來訪問indexes
的第i個元素-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));
Expression.Constant(0)
導致indexes
中的第一個元素的ArrayIndexExpression
, Expression.Constant(1)
地導致第二個元素的ArrayIndexExpression
。
現在編譯了表達式樹後,我們可以調用委託來訪問MyProperty
第一個實例的AnotherProperty
的第二個int值:
ClassA a = new ClassA
{
MyProperty = new[] { new ClassB
{
AnotherProperty = new[] { 1, 4 }
}
};
int result = f(x, new[] { 0, 1 });