2011-12-08 21 views
0

我想用反射來恢復類型信息。我有給定一個集合對象,想分配給一個特定類型的局部變量

public Foo(object coll, string tValue) 
{ 
    var x = col1 as IList; 
    if (x != null) 
     x.Action(); 

    var y = col1 as IDictionary; 
    if (y != null) 
     y.Action(); 
} 

但是想有

public Foo(object coll, string tValue) 
{ 
    var x = col1 as IList<TValue>; 
    if (x != null) 
     x.Action(); 

    var y = col1 as IDictionary<int, TValue>; 
    if (y != null) 
     y.Action(); 
} 

是否有可能在到達和使用通用接口,而不是老派非泛型集合接口,只給出所包含的類名?

一旦建立了局部變量類型,我想避免在循環集合時支付反射和動態調用懲罰。

另一個例子,也許更加清晰:

 var list = new Dictionary<int, MyObject>(); 
    list.Add(100, new MyObject()); 

    object listObject = list; 

    var x = listObject as IDictionary<int, dynamic>; 
    if (x != null) 
    { 
     foreach (var entry in x) 
     { 
      Console.WriteLine(entry.Key); 
      Console.WriteLine(entry.Value); 
     } 
    } 

x是空...

+0

快速評論,您可以使用「is」關鍵字而不是Blah!= null。 – Bashwork

+0

我認爲Bashwork的觀點是你可以做'if(col1是IList)((IList)col1).Action();' –

+0

在你調用這個函數的地方已知類型嗎?是否可以使用泛型(即,使Foo函數通用)。 – wllmsaccnt

回答

2

我不知道,如果你打算在集合中來調用泛型集合的方法爲每個項目或者你只需要泛型集合中的值。

對於第三塊代碼,您可以繼續使用非通用接口並使用枚舉器。

 var x = listObject as IDictionary; 
     if (x != null) 
     { 
      var en = x.GetEnumerator(); 
      while(en.MoveNext()) 
      { 
       Console.WriteLine(en.Key); 
       Console.WriteLine(en.Value); 
      } 
     } 

如果要調用一個方法不知道確切的泛型類型爲通用的IList或IDictionary的,那麼你就必須使用MethodInfo.Invoke。在循環之外緩存MethodInfo以獲得較小的性能提升。 CreateDelegate會更快,但您需要知道確切的泛型類型。你可以通過表達式樹來解決這個問題,但是維護的代碼量可能不值得提升性能。查看Jon Skeets文章中的MagicMethod文章 Making reflection fly and exploring delegates

+0

對Skeet博客的教育參考+1。 – GregC

+0

我真的很喜歡弗拉基米爾在討論基於表達式的解決方案。 – GregC

+0

這是一篇非常好的文章。基準,多種解決方案,以及從問題到解決方案的思維過程的細節。 :) –

相關問題