0

属性索引器数组

尝试动态生成以下 lambda 表达式:

Expression<Func<Program, string>> y = _ => _.x[0];

其中 x 是 List 类型

尝试使用 Expression.MakeIndex,但它似乎正在弹跳异常:

Expression.MakeIndex(parameter, typeof (Program).GetProperty("x"), new[] {Expression.Constant(0)})

异常消息:

为调用方法“System.Collections.Generic.List`1[System.String] get_x()”提供的参数数量不正确

我怎样才能做到这一点?

4

2 回答 2

5

这里有两个操作:

  1. x_parameter
  2. 访问索引 0 处的项目

您需要为此创建两个单独的表达式:

var property = Expression.Property(parameter, typeof (Program).GetProperty("x"));
var itemAtPosition0 = Expression.MakeIndex(property, typeof(List<string>).GetProperty("Item"),
                     new [] { Expression.Constant(0) });

"Item"指索引器属性的默认名称。有关此名称以及如何可靠地检测所使用的实际名称的更多信息,请查看此答案

于 2013-02-15T08:39:59.147 回答
3

这个答案假设Program类是这样定义的:

public class ProgramZ
{
    public List<string> x { get; set; }
}

问题是您正在尝试将索引应用于Program.x属性,而实际上它应该应用于List<string>的索引器属性(称为Item)。

最后,为了能够调用表达式,您需要将其包装成 lambda。

这是执行此操作的代码:

var expr =
    Expression.Lambda<Func<Program, string>>(
        Expression.MakeIndex(
                Expression.Property(
                    parameter,
                    typeof(Program).GetProperty("x")),
                typeof(List<string>).GetProperty("Item"),
                new[] { Expression.Constant(0) }),
        parameter);

以下是调用表达式的方法:

var instance = new ProgramZ { x = new List<string> { "a", "b" } };

Console.WriteLine(expr.Compile().Invoke(instance));

此代码将按a预期输出 。

于 2013-02-15T08:42:29.233 回答