使用表达式树使用索引器访问类型的元素
Accessing elements of types with indexers using expression trees
假设我有这样的类型:
class Context
{
SomeType[] Items { get; set; }
}
我希望能够使用表达式树访问特定的 Items
元素。假设我需要索引 0
处的元素。我可以像下面那样做,一切都按预期进行:
var type = typeof (Context);
var param = Expression.Parameter(typeof (object));
var ctxExpr= Expression.Convert(param, context);
var proInfo = type.GetProperty("Items");
Expression.ArrayIndex(Expression.Property(ctxExpr, proInfo), Expression.Constant(0));
如果我将上下文类型更改为包含 .NET 提供的 List<SomeType>
,而不是 array
,即
class Context
{
List<SomeType> Items { get; set; }
}
相同的表达式导致以下错误:
System.ArgumentException: Argument must be array at
System.Linq.Expressions.Expression.ArrayIndex(Expression array,
Expression index)
我的问题是,如何编写相应的表达式来访问 List<>
或任何集合声明索引器的适当索引下的项目?例如。是否有某种方法可以使用表达式树检测并转换此类集合为 array
适当类型?
索引器实际上只是一个带有额外参数的 属性,所以您需要:
var property = Expression.Property(ctxExpr, proInfo);
var indexed = Expression.Property(property, "Item", Expression.Constant(0));
其中 "Item"
是此处 indexed property 的名称。
(如果你事先不知道 属性 的名称,通常是 Item
但你总是可以通过反射找到它,通过使用索引器参数查找所有属性。)
假设我有这样的类型:
class Context
{
SomeType[] Items { get; set; }
}
我希望能够使用表达式树访问特定的 Items
元素。假设我需要索引 0
处的元素。我可以像下面那样做,一切都按预期进行:
var type = typeof (Context);
var param = Expression.Parameter(typeof (object));
var ctxExpr= Expression.Convert(param, context);
var proInfo = type.GetProperty("Items");
Expression.ArrayIndex(Expression.Property(ctxExpr, proInfo), Expression.Constant(0));
如果我将上下文类型更改为包含 .NET 提供的 List<SomeType>
,而不是 array
,即
class Context
{
List<SomeType> Items { get; set; }
}
相同的表达式导致以下错误:
System.ArgumentException: Argument must be array at System.Linq.Expressions.Expression.ArrayIndex(Expression array, Expression index)
我的问题是,如何编写相应的表达式来访问 List<>
或任何集合声明索引器的适当索引下的项目?例如。是否有某种方法可以使用表达式树检测并转换此类集合为 array
适当类型?
索引器实际上只是一个带有额外参数的 属性,所以您需要:
var property = Expression.Property(ctxExpr, proInfo);
var indexed = Expression.Property(property, "Item", Expression.Constant(0));
其中 "Item"
是此处 indexed property 的名称。
(如果你事先不知道 属性 的名称,通常是 Item
但你总是可以通过反射找到它,通过使用索引器参数查找所有属性。)