2013-11-26 75 views
2

我在想如何獲取所有類型的對象,而不是指向另一個類。如何在C中獲取對象的所有簡單屬性#

例如這將包括字符串,整數,日期時間等 但不包括指針收藏,或其它自定義類

我有以下,但它似乎並沒有返回字符串:

PropertyInfo[] properties = typeOfObject.GetProperties(); 

foreach (PropertyInfo property in properties.Where(p => !p.PropertyType.IsClass)) 
{ 
} 

由於Leri問我 - 我計劃採用一個對象的原始副本,沒有集合/類等,因此它必須包含所有原始類型,字符串,日期時間以及其他任何存在的東西。

+0

爲什麼你想要它?聽起來像你正在做一些映射..添加更大的上下文將讓我們給出更準確的答案。 – Leri

+0

這不是重複的。我知道如何獲得屬性,但我不知道根據我的問題獲取指定屬性的好方法。 Leri - 我在底部更新了我的問題 – eyeballpaul

+0

[檢查對象是否爲非基類型]可能的重複(http://stackoverflow.com/questions/13128028/check-if-an-object-is-non-鹼基類型) – Servy

回答

5

因爲String是一類,而不是像Int32Double一個結構等

如果你想要的一切,這不是一類,但包括字符串,只是指定!

foreach (PropertyInfo property in 
     properties.Where(p => !p.PropertyType.IsClass 
            || p.PropertyType == typeof(String))) 
{ 
} 
+0

|| p.PropertyType == typeof(DateTime) –

+0

除了字符串以外,還有其他的內置類型會丟失什麼? Emil還提到了DateTime,還有其他的嗎? – eyeballpaul

+1

Emil的評論是錯誤的,DateTime不是一個類,所以你不必爲此例外。然而,正如我在我的回答中所說的,你可以擁有一個引用其他類的結構體(它不是一個類,它將通過你的測試)。 – Luaan

2

你的代碼也會給你所有的結構體,它們本身可以包含對集合等的引用,所以它不會這樣做。

您最好的選擇可能是要求IsPrimitive(這會是int,short等),並添加你想要的任何其他已知的類型,比如字符串,日期時間等

+0

好吧,我從來沒有想過Structs。在這種情況下,我實際上不會有任何結構,但是爲了將來打樣,最好現在就照顧他們。所以,除了字符串,日期時間,什麼不會包含在「IsPrimitive」中?那可空的類型呢? – eyeballpaul

+0

MSDN說:「原始類型是布爾,字節,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single。」 可空類型將會非常棘手,基本上你必須得到泛型類型定義--p.PropertyType.GetGenericTypeDefinition()== typeof(Nullable <>)'。但是,可爲空的值可以包含任何值類型,因此您需要根據類型參數檢查允許的類型列表。 – Luaan

0

好了,你的精緻問題,更好的答案是這樣的:如果你能夠對一個變量調用GetType(),則返回一個對象,並且可以反射該對象以獲取基礎類型。您還可以詢問類型是否爲某種其他現有類型的實例,這可能有助於確定運行時類型的安全性(「如果我將此實體視爲Cat類型的對象,我的代碼是否會拋出異常?」)

所以我認爲你想要做的就是調用GetType()。然後你可以用返回的類型對象做很多事情。其中之一是測試完全匹配,例如這樣:「if(x.GetType()。Equals(typeof(int)))... ...

實際上有幾種方法可以做到這一點,我只是做了精確匹配,但注意到你可以使用typeof(int)來獲得一個Type對象,它將成爲int類型的真正的底層類型表示,即使int是一個基類鍵入C#,因此int類型的東西不是對象 - 在運行時,它由值表示,而不是由引用表示。這是因爲typeof()在編譯時已解析。這可能是你需要做的。

+0

我已更新我的問題,爲什麼我正在嘗試這樣做 – eyeballpaul

0

我決定做一個混合物這裏有幾個解決方案。

首先,由於結構等問題,我決定保留Leri提到的允許類型列表。第二,根據Luaan的評論,我寫了一個處理空白的方法。

所以溶液如下:

的代碼爲通過屬性

foreach (PropertyInfo property in properties) 
{ 
if (this.IsTypeASimpleType(property.PropertyType) && 
    property.CanWrite) 
{ 
} 
} 

迭代然後用於檢查代碼,如果類型是正確的

private bool IsTypeASimpleType(Type typeToCheck) 
    { 
     var typeCode = Type.GetTypeCode(this.GetUnderlyingType(typeToCheck)); 

     switch (typeCode) 
     { 
      case TypeCode.Boolean: 
      case TypeCode.Byte: 
      case TypeCode.Char: 
      case TypeCode.DateTime: 
      case TypeCode.Decimal: 
      case TypeCode.Double: 
      case TypeCode.Int16: 
      case TypeCode.Int32: 
      case TypeCode.Int64: 
      case TypeCode.SByte: 
      case TypeCode.Single: 
      case TypeCode.String: 
      case TypeCode.UInt16: 
      case TypeCode.UInt32: 
      case TypeCode.UInt64: 
       return true; 
      default: 
       return false; 
     } 
    } 

和代碼,以處理空白

private Type GetUnderlyingType(Type typeToCheck) 
    { 
     if (typeToCheck.IsGenericType && 
      typeToCheck.GetGenericTypeDefinition() == typeof(Nullable<>)) 
     { 
      return Nullable.GetUnderlyingType(typeToCheck); 
     } 
     else 
     { 
      return typeToCheck; 
     } 
    } 

現在,switch語句可能已被更改爲允許的類型列表,但最終的遊戲將是相同的。

相關問題