C# 数组属性的表达式树
假设我们有这个班C# 数组属性的表达式树,c#,arrays,expression-trees,C#,Arrays,Expression Trees,假设我们有这个班 class ClassA { public ClassB[] MyProperty { get; set; } } class ClassB { public int[] AnotherProperty { get; set; } } 现在,我想访问ClassA给定实例的另一个属性的值,以及反映这两个数组的索引数组,因此{3,5}例如,表示顶级中的第四个元素(计算结果为MyProperty),第二级中的第六个元素(AnotherProperty)。因此,我将通
class ClassA
{
public ClassB[] MyProperty { get; set; }
}
class ClassB
{
public int[] AnotherProperty { get; set; }
}
现在,我想访问ClassA
给定实例的另一个属性的值,以及反映这两个数组的索引数组,因此{3,5}
例如,表示顶级中的第四个元素(计算结果为MyProperty
),第二级中的第六个元素(AnotherProperty
)。因此,我将通过表达式树创建一个Func
:
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);
var instanceArgument=Expression.Parameter(typeof(MyClass),“x”);
var indexesArgument=Expression.Parameter(typeof(int[]),“i”);
var expr=实例参数;
expr=Expression.Property(expr,“MyProperty”);
expr=表达式.ArrayIndex(expr,?);
expr=Expression.Property(expr,“另一个属性”);
expr=表达式.ArrayIndex(expr,?);
var f=表达式.Lambda(表达式、实例参数、索引参数);
正如您所见,我不确定如何为表达式提供索引。我知道我必须使用反映传递给我们的代表的索引的索引,但是如何访问3
和5
?我们需要进一步的数组索引表达式
来访问中的第I个元素>索引
-参数:
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)
导致索引中第一个元素的ArrayIndexExpression
,Expression.Constant(1)
相应地指向第二个元素
现在,在编译完表达式树之后,我们可以调用委托来访问MyProperty
中第一个实例的AnotherProperty
的第二个int值:
ClassA a = new ClassA
{
MyProperty = new[] { new ClassB
{
AnotherProperty = new[] { 1, 4 }
}
};
int result = f(x, new[] { 0, 1 });
我们需要进一步的ArrayIndexExpression
来访问索引中的第i个元素
-参数:
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)
导致索引中第一个元素的ArrayIndexExpression
,Expression.Constant(1)
相应地指向第二个元素
现在,在编译完表达式树之后,我们可以调用委托来访问MyProperty
中第一个实例的AnotherProperty
的第二个int值:
ClassA a = new ClassA
{
MyProperty = new[] { new ClassB
{
AnotherProperty = new[] { 1, 4 }
}
};
int result = f(x, new[] { 0, 1 });
如果你想让一个函数正好接受两个整数,你应该让它接受两个整数,而不是一个你希望大小正好为2的数组。此外,因为这不是动态的,所以你可以使用lambda来构造表达式。好吧,树更具动态性,因为要访问的属性来自字符串,或者类似于MyProperty[3]的ing。另一个属性[5]
。我从这个字符串中提取属性和索引的名称如果你想让一个函数只接受两个整数,你应该让它接受两个整数,而不是一个你希望大小正好为2的数组。此外,因为这不是动态的,所以你可以使用lambda来构造表达式。嗯,树因为要访问的属性来自一个字符串,比如MyProperty[3]。另一个属性[5]
。我从这个字符串中提取属性和索引的名称。我认为这一点非常明显,因为您正在构建类似(x,索引)=>x.MyProperty[index[0]]的表达式。另一个属性[索引[1]]
(很容易看到双数组索引和常量)@IvanStoev当然,现在这对我来说是显而易见的。但是,如果你不像我那样熟悉表达式树,那么它就不一定是显而易见的。无论如何,除了OP.Hehe,几乎所有关于SO的问题对某人来说都是显而易见的。当然。但是表达式的好处是,你总是可以创建编译时表达式,并使用调试器检查它,以使其符合see里面是什么:)@IvanStoev虽然我很欣赏你的支持票,但你不应该仅仅因为它之前被否决就这样做。然而,你应该这样做,因为问题和/或答案的质量——我希望达到这一点。一点问题也没有。不管我怎么说,我认为这个问题和答案不值得否决票。干杯。我认为这很明显这是因为您正在构建表达式,如(x,index)=>x.MyProperty[index[0]]。另一个属性[index[1]]
(很容易看到双数组索引和常量)@IvanStoev当然,现在这对我来说是显而易见的。但是,如果你不像我那样熟悉表达式树,那么它就不一定是显而易见的。无论如何,除了OP.Hehe,几乎所有关于SO的问题对某人来说都是显而易见的。当然。但是表达式的好处是,你总是可以创建编译时表达式,并使用调试器检查它,以使其符合see其中的内容:)@IvanStoev虽然我很感激你的支持,但你不应该仅仅因为之前的投票被否决就这样做。但是你应该这样做,因为我希望获得的问题和/或答案的质量。一点问题也没有。不管我怎么说,我认为这个问题和答案不值得否决。干杯。