2011-06-26 84 views
16

有鑑於此:有沒有一種通用的方法來檢測一個屬性的類型是一個枚舉類型?

class InvoiceHeader { 
    public int InvoiceHeaderId { get; set; } 
    IList<InvoiceDetail> LineItems { get; set; } 
} 

我目前使用此代碼來檢測,如果一個類有一個集合屬性:

void DetectCollection(object modelSource) 
{  
    Type modelSourceType = modelSource.GetType(); 
    foreach (PropertyInfo p in modelSourceType.GetProperties()) 
    { 
     if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)) 
     { 
      System.Windows.Forms.MessageBox.Show(p.Name); 
     } 
    } 
} 

是否有檢測,如果了LineItem的一般方式是一個枚舉類型?有些會使用其他枚舉類型(例如ICollection),而不是IList。

回答

38

你的代碼實際上並不是c哎喲,如果屬性是Enumerable類型,但如果他們是通用IList的。試試這個:

if(typeof(Enumerable).IsAssignableFrom(p.PropertyType)) 
{ 
    System.Windows.Forms.MessageBox.Show(p.Name); 
} 

或者這

if (p.PropertyType.GetInterfaces().Contains(typeof(IEnumerable))) 
{ 
    System.Windows.Forms.MessageBox.Show(p.Name); 
} 
+2

p.PropertyType.GetInterfaces()。Contains(typeof(IEnumerable))&& p.PropertyType!= typeof(String)否則一個String屬性也會傳遞這個condigion – Oleg

+0

並不是所有的枚舉都是'IEnumerable'我相信帶'GetEnumerator'函數的任何東西實際上都可以在'foreach'語句中使用 –

+2

儘管它可能有點明顯,但值得指出的是字符串也是一個枚舉類型。如果有人想檢查一個屬性是否是任何類型的列表或集合,使用ICollection會更合適。 – XtraSimplicity

1

IEnumerable是C#中所有Enumerable類型的基類型,因此您可以檢查一般屬性是否屬於該類型。

但應該注意的是,C#在綁定Sugar語法(例如foreach循環)方面是特殊的,它綁定到方法(因此對於完整的檢查,您應該檢查屬性是否包含名爲GetEnumerator的方法IEnumerable.GetEnumerator或IEnumerable.GetEnumerator)

+0

你不能簡單地檢查'IEnumerable的'與反思,作爲一個ICollection的''正是在外部,而不是'的IEnumerable '。 – Femaref

+2

Fermaref你是什麼意思? 'ICollection '繼承'IEnumerable',所以'IsAssignableFrom'測試應該按照預期工作。 – CodesInChaos

+0

'is'比較對象實例和類/結構等。定義。由於'p.PropertyType'的類型爲'System.Type',並且沒有實現'IEnumerable',它總會返回'false'。 – Femaref

2
if (invoiceHeader.LineItems is IEnumerable) { 
    // LineItems implements IEnumerable 
} 

如果invoiceHeader的類型是在編譯時未知這是行不通的。在這種情況下,我想知道爲什麼沒有一個通用的接口,因爲使用反射來找到一個集合屬性是相當可疑的。

+0

RE:「在這種情況下,我想知道爲什麼沒有一個通用的接口,因爲使用反射來查找集合屬性是非常可疑的。」 - 我爲NHibernate創建了一個擴展庫 – Hao

相關問題