1

我想实现一种方法,该方法允许我以后期绑定/动态方式访问未知/匿名对象(-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 我还有哪些其他选项可以实现与上面所示类似的东西,但可能更简单、性能更高等?

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

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

4

2 回答 2

2

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

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

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

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

于 2010-09-07T13:46:09.040 回答
1

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

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

于 2010-09-07T13:58:54.073 回答