2010-05-10 30 views
1

背景IEnumerable的<T>和反射

工作在.NET 2.0這裏,反射一般列表。我最初使用t.IsAssignableFrom(typeof(IEnumerable))來檢測我正在遍歷的屬性是否支持IEnumerable接口。 (因此我可以安全地將對象投射到它)

但是,當對象爲BindingList<T>時,此代碼未評估爲True

下一頁

我試圖用t.IsSubclassOf(typeof(IEnumerable))並沒有任何運氣無論是。

代碼

/// <summary> 
    /// Reflects an enumerable (not a list, bad name should be fixed later maybe?) 
    /// </summary> 
    /// <param name="o">The Object the property resides on.</param> 
    /// <param name="p">The Property We're reflecting on</param> 
    /// <param name="rla">The Attribute tagged to this property</param> 
    public void ReflectList(object o, PropertyInfo p, ReflectedListAttribute rla) 
    { 
     Type t = p.PropertyType; 
     //if (t.IsAssignableFrom(typeof(IEnumerable))) 
     if (t.IsSubclassOf(typeof(IEnumerable))) 
     { 
      IEnumerable e = p.GetValue(o, null) as IEnumerable; 

      int count = 0; 
      if (e != null) 
      { 
       foreach (object lo in e) 
       { 
        if (count >= rla.MaxRows) 
         break; 

        ReflectObject(lo, count); 

        count++; 
       } 
      } 
     } 
    } 

意圖

我想基本上標籤列表我想用ReflectedListAttribute,以反映通過,並呼籲有它的屬性此功能。 (已經工作)

一旦這個函數裏面,考慮到物業所在的對象,以及相關的PropertyInfo,得到屬性的值,將其轉換爲一個IEnumerable(假設這是可能的),然後通過每個孩子迭代和用count變量調用ReflectObject(...)

回答

11

當你做as IEnumerable和變量不爲空時,你知道它實現IEnumerable接口。

你鴕鳥政策需要的代碼:

Type t = p.PropertyType; 
//if (t.IsAssignableFrom(typeof(IEnumerable))) 
if (t.IsSubclassOf(typeof(IEnumerable))) 
{ 

這將是不夠的:

public void ReflectList(object o, PropertyInfo p, ReflectedListAttribute rla) 
{ 
    IEnumerable e = p.GetValue(o, null) as IEnumerable; 

    int count = 0; 
    if (e != null) 
    { 
     foreach (object lo in e) 
     { 
      if (count >= rla.MaxRows) 
       break; 
      ReflectObject(lo, count); 
      count++; 
     } 
    } 
} 
+0

哇,這是當你發現你很久以前嘲笑它並且不起作用時,當你回到舊代碼時會發生什麼。現在你提到它了,我沒有模糊的想法,我錯過了那個> _ <。謝謝 – Aren 2010-05-10 11:53:55

3

爲什麼你的if語句呢?

您已經做了var e = ... as IEnumerable,之後只是檢查是否爲空。

這還不夠嗎?

1

這些工作。 :)

A List擴展Collection。所以,測試對他們來說是不同的。 A Dictionary有兩個內部容器。因此,一個相同的測試。

public static bool IsList(object obj) 
{ 
    System.Collections.IList list = obj as System.Collections.IList; 
    return list != null; 
} 

public static bool IsCollection(object obj) 
{ 
    System.Collections.ICollection coll = obj as System.Collections.ICollection; 
    return coll != null; 
} 

public static bool IsDictionary(object obj) 
{ 
    System.Collections.IDictionary dictionary = obj as System.Collections.IDictionary; 
    return dictionary != null; 
} 



使用例 -

if (IsDictionary(fieldObject)) //key-value type collection? 
{ 
    System.Collections.IDictionary dictionary = fieldObject as System.Collections.IDictionary; 
    foreach (object _ob in dictionary.Values) 
    { 
     //do work 
    } 
    // dictionary.Clear(); 
} 
else //normal collection 
{ 
    if (IsCollection(fieldObject)) 
    { 
     System.Collections.ICollection coll = fieldObject as System.Collections.ICollection; 
     foreach (object _ob in coll) 
     { 
      //do work 
     } 

     if (IsList(fieldObject)) 
     { 
      //System.Collections.IList list = fieldObject as System.Collections.IList; 
      //list.Clear(); // <--- List's function, not Collection's. 
     } 
    } 
} 
+0

我不會推薦使用這種模式,因爲它會執行冗餘模式。預期在使用「as」之後進行空檢查,這會導致更簡單的代碼(不需要額外的方法調用)和單個cast(請參閱Jens的答案)。 – 2010-05-10 11:57:44

+0

我明白了。這些是我發佈的功能,用於重用目的。 Jens方法通過內嵌代碼來簡化這些操作,但也爲重複提供了空間。 OP現在可以選擇。 – Nayan 2010-05-10 12:26:55

4

MSDN

的IsSubclassOf方法不能用來 確定接口 是否從另一個接口派生,或 是否類實現了一個 接口使用GetInterface方法爲目的

而且你IsAssignableFrom的實施是不對的,你應該使用這樣的:

typeof(IEnumerable).IsAssignableFrom(t) 

如果IEnumerable的t時付諸實施。這應返回true ..

相關問題