使用表达式树使用索引器访问类型的元素

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 但你总是可以通过反射找到它,通过使用索引器参数查找所有属性。)