我想实现一个允许我以后期绑定/动态方式访问未知/匿名对象(-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
方法中使用string
和Get()
的原因。
答案 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(并且作为附加的好处具有递归图形支持)。最后,您可以使用相同的方法将对象转储到字典词典中。