【问题标题】:Specifying generic type when accessing a c# dynamic object访问 c# 动态对象时指定泛型类型
【发布时间】:2011-05-07 17:33:53
【问题描述】:

是否可以从动态对象中获得通用结果。我正在尝试围绕 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?
}

谢谢。

【问题讨论】:

  • 我会假设答案(iow 类型 args)在 binder 中可用。
  • 已经快一年了,但是你找到解决这个问题的方法了吗?
  • 不。最后,我只需要使用 List。新的 json.net 支持动态特性,所以我正在考虑放弃 DynamicJson 作为默认实现。

标签: .net generics dynamic c#-4.0


【解决方案1】:

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

最简单的实现是在DynamicJSON类上实际实现GetValues&lt;T&gt;()。

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&lt;T&gt;() 方法对您来说不可行,您可以实现TryInvokeMember() 以返回已实现@987654322@ 的方法。当 .NET 尝试将 GetValues&lt;int&gt;() 的结果转换为 List&lt;int&gt;() 时,您被覆盖的 TryConvert() 方法将被调用,并使用 List&lt;int&gt;() 作为“转换绑定器类型”。

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());
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    相关资源
    最近更新 更多