如何动态/后期绑定属性?

时间:2010-09-07 13:41:36

标签: dynamic c#-4.0 late-binding

我想实现一个允许我以后期绑定/动态方式访问未知/匿名对象(-graph)属性的方法(我甚至不知道如何正确调用它)。

以下是我想要实现的一个例子:

// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };

// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I"); 

这是一个使用“经典”反射的简单实现:

public static object Get(object obj, string expression)
{
    foreach (var name in expression.Split('.'))
    {
        var property = obj.GetType().GetProperty(name);
        obj = property.GetValue(obj, null);
    }
    return obj;
}

我还有哪些其他选项可以使用C#/ .NET 4实现类似于上面显示的内容,但可能更简单,性能更高等等?

也许有办法实现同样的事情,这可以让我使用lambda表达式而不是字符串来指定expression?表达树是否会以任何方式提供帮助(例如,如this question所示)?

更新:对象和表达式通过Web服务调用传递给我的代码。这就是我在object方法中使用stringGet()的原因。

2 个答案:

答案 0 :(得分:2)

实际只将表达式作为字符串吗?它是在编译时知道的,只是类型本身不知道(或难以表达)?如果是这样的话:

dynamic d = a;
int i = d.B.C.I;

如果真的只将它作为一个字符串(例如用户输入的数据),这会让生活变得更加艰难,而且C#4功能都没有真正帮助你。您可以将其评估为IronPython脚本或类似的东西......

编辑:好的,在更新之后听起来你处于后一种情况 - 在这种情况下,我不知道比使用反射更好的方式。为UI构建的一些内置属性绑定可能有所帮助,但我不知道访问它的干净方法。

答案 1 :(得分:1)

如果要使用C#样式,可以将Mono编译器用作应用程序中的服务。我在这里描述如何做到这一点: Mono Compiler as a Service (MCS)

作为替代方法,您可以使用反射将所有对象的属性放入ExpandoObject,然后像字典一样使用它(因为ExpandoObject实现了IDictionary)。或者,您可以使用JSON.NET并调用JObject.FromObject,它将常规对象转换为可以类似字典样式访问的JObject(并且作为附加的好处具有递归图形支持)。最后,您可以使用相同的方法将对象转储到字典词典中。