动态获取动态对象的值

Dav*_*bbo 9 c# dynamic c#-4.0

是的,标题听起来有点令人困惑,所以我会解释我的意思:假设你有一个C#4.0'动态'对象,以及一个属性的名称.你将如何从动态对象中检索该属性?

换句话说,你将如何实现:

public static object GetDynamicValue(dynamic o, string name) { ... }
Run Code Online (Sandbox Code Playgroud)

另一种说法是我试图将动态对象视为IDictionary.

请注意,这里反射可能不是一个选项,因为动态对象可能是一个不基于反射的自定义实现(例如,通过扩展DynamicObject并做自己的事情).

Jon*_*eet 14

你必须建立一个呼叫站点,创建一个绑定器等.

看看会发生什么的最简单方法是编译:

public static object GetDynamicValue(dynamic o, string name)
{
    return o.Foo;
}
Run Code Online (Sandbox Code Playgroud)

然后使用Reflector对其进行反编译并找出它正在做的事情.请注意,它会非常复杂 - 您需要将其从单个静态缓存调用站点更改为在每次调用时创建新站点.

这是一个有效的例子......但是它是否完全正确是另一回事:)(我完全按照上面的建议完成了这个.)

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Dynamic;
using System.Runtime.CompilerServices;

class Test
{
    public static object GetDynamicValue(dynamic o, string name)
    {
        CallSite<Func<CallSite, object, object>> site 
            = CallSite<Func<CallSite, object, object>>.Create
            (Binder.GetMember(CSharpBinderFlags.None, name, 
             typeof(Test), new CSharpArgumentInfo[] 
             { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
        return site.Target(site, o);
    }

    static void Main()
    {
        Console.WriteLine(GetDynamicValue("hello", "Length"));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它与成员可访问的内容相关 - 您可以使用此代码获取Test的私有成员,但不能访问其他类型的私有成员. (3认同)