0

我得到以下代码的异常:

public class InnerClass 
{
    public object Value { get; set; }
}

public class OuterClass
{
    // If I change the type of this property to "InnerClass" the exception is removed
    public object Inner { get; set; }
}

private static void SmallSandbox()
{
    var outer = new OuterClass()
    {
        Inner = new InnerClass()
        {
            Value = 2
        }
    };

    var p = Expression.Parameter(typeof(OuterClass), "p");

    Func<OuterClass, object> e = Expression.Lambda<Func<OuterClass, object>>(
        Expression.Property(Expression.Property(p, "Inner"), "Value"),
        p
    ).Compile();

    var a = new[] { outer }.Select(e).First();
    Console.WriteLine(a);
}

更改public object Inner { get; set; }public InnerClass Inner { get; set; }删除异常。这不是一个选项,因为我让我的程序的使用者最终提供属性名称"Value"和关联的对象 - 它无法提前知道。

我能做些什么来修复我的异常?

4

2 回答 2

2

Inner被声明为object. 显然, anobject不包含Value属性。在尝试访问该属性之前,您需要将该表达式“转换”为预期的类型。这相当于向表达式添加强制转换。

Func<OuterClass, object> e = Expression.Lambda<Func<OuterClass, object>>(
    Expression.Property(
        Expression.Convert(Expression.Property(p, "Inner"), typeof(InnerClass)),
        "Value"
    ),
    p
).Compile();
于 2013-08-11T03:51:12.837 回答
1

这似乎工作......

        using Microsoft.CSharp.RuntimeBinder;


        var p = Expression.Parameter(typeof(OuterClass), "p");
        var binder = Binder.GetMember(CSharpBinderFlags.None, "Value", outer.Inner.GetType(), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
        var e = Expression.Lambda<Func<OuterClass, object>>(
            Expression.Dynamic(binder, typeof(object) ,Expression.Property(p, "Inner")),
            p
        ).Compile();
于 2013-08-11T04:13:51.340 回答