访问c#动态对象时指定泛型类型

时间:2010-11-10 07:39:43

标签: .net generics dynamic c#-4.0

是否可以从动态对象获取通用结果。我正在尝试围绕Json.Net JObject类创建一个动态包装器。它有效,但在返回数组时,我总是必须将它们作为List<object>返回。我更喜欢的是List<T>

dynamic d = new DynamicJson(json);
var result = d.GetValues<string>();
var d = (string[])d.tags;

DynamicJson是一个自定义类。此外,当使用泛型参数进行调用时,如何将其传递给动态对象?

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
   //how do I determine the generic types in this code?
   //can I just do the  casting?
}

谢谢。

1 个答案:

答案 0 :(得分:0)

据我所知,泛型参数永远不会传递给TryGetMember()TryInvokeMember覆盖。 MSDN文档仅显示GetMemberBinderGetInvokeBinder对象传入的简单字符串名称。

最简单的实现是在GetValues<T>()类上实际实现DynamicJSON

public List<T> GetValues<T>()
{
    Console.WriteLine("Called with generic parameter {0}", typeof(T));
    return new List<T>();
}

当我运行这个简单的测试时,泛型参数是.NET Int32类型:

dynamic json = new DynamicJSON();
json.GetValues<int>()

如果您无法实施GetValues<T>()方法,则可以实施TryInvokeMember()以返回已实施TryConvert()的方法。当.NET尝试将GetValues<int>()的结果转换为List<int>()时,将使用TryConvert()作为“转换活页夹类型”调用被覆盖的List<int>()方法。

public class DynamicJSON : DynamicObject
{
    public override bool TryInvokeMember(InvokeMemberBinder binder, Object[] args, out Object result)
    {
        if (binder.Name == "GetValues")
        {
            result = new DynamicValues();
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    private class DynamicValues : DynamicObject
    {
        public override bool TryConvert(ConvertBinder binder, out Object result)
        {
            Console.WriteLine("Converting dynamic values to {0}", binder.Type);

            if (binder.Type == typeof(List<int>))
            {
                result = new List<int>();
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }
    }
}

public class Test
{
    public static void Main(string[] args)
    {
        dynamic json = new DynamicJSON();
        List<int> values = json.GetValues();
        Console.WriteLine(values.GetType());
    }
}