2010-11-10 91 views
2

是否可以從動態對象中獲取泛型結果。我試圖圍繞Json.Net JObject類創建一個動態包裝。它的工作原理,但返回一個數組時,我總是不得不返回它們作爲List<object>。我本來希望的是List<T>指定訪問c#動態對象時的泛型類型

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? 
} 

謝謝。

+0

我會假設答案(低於類型參數)在'binder'中是有效的。 – leppie 2010-11-10 08:13:59

+0

差不多一年之後,但是你找到了解決這個問題的辦法嗎? – 2011-08-21 22:30:31

+0

Nah。最後我只好與列表一起工作。新的json.net支持動態特性,所以我在考慮爲DynamicJson刪除默認實現。 – ritcoder 2011-08-27 16:33:59

回答

0

從我所知道的,通用參數永遠不會傳遞到TryGetMember()TryInvokeMember覆蓋。 MSDN文檔僅顯示GetMemberBinderGetInvokeBinder對象傳入的簡單字符串名稱。

最簡單的實現是在DynamicJSON類上實際實現GetValues<T>()

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>()時,將使用List<int>()作爲「轉換綁定器類型」調用覆蓋的TryConvert()方法。

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