2010-04-26 98 views
6

如何編寫一個簡單的方法,檢查具體類型是否是一個自定義結構(使用public struct { };創建)。如何確定.NET類型是否是一個自定義結構?

檢查Type.IsValueType是不夠的,因爲它也是真實的intlong等, 並增加了檢查!IsPrimitiveType將不排除decimalDateTime也許有些其他值類型。我知道,大多數的內置的值類型實際上是「結構」,但我只想要檢查的「自定義結構」

這些問題大多是相同的,但沒有答案,我需要:

編輯:從答案中提到 「檢查 '系統' 前綴」 是最穩定(雖然它仍然是黑客)。我最終決定創建一個屬性,你必須用這個結構來裝飾結構,以便框架將它作爲一個自定義結構來提取。 (我想另一種選擇是創建一個空的接口,讓結構實現一個空接口,但屬性的方式似乎更優雅)

這是我原來的自定義結構檢查,如果有人如果有興趣:

type.IsValueType && !type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum 
+1

出於好奇,你爲什麼要檢測這個? – Joren 2010-04-26 13:53:26

+0

流利的NHibernate +自動映射:將所有自定義的結構設置爲組件(值對象);設置任何其他值類型爲一個組件(如DateTime或十進制)將崩潰整個框架(至少它在單聲道下) – SztupY 2010-04-26 13:58:39

+0

Add on!type.IsEnum – 2010-08-18 12:10:42

回答

5

那麼,日期時間,小數等符合您的要求。就CLR而言,它們是定製的結構。黑客,但你可以檢查,看看命名空間是否以「系統」開頭。

+0

當然,您自己的命名空間可以以System ...開頭: )沒有人會這樣做,對吧? – 2010-04-30 15:10:07

+2

是的,這就是我稱之爲黑客的原因。 – 2010-04-30 16:32:24

+0

@MattGreer:順便說一句,我想不出來:)謝謝 – 2014-01-09 23:01:55

8

在框架中定義的結構和自己定義的結構之間沒有區別。

一對夫婦的想法可能是:

  • 保持框架結構的白名單,並排除;
  • 確定類型在其中定義的程序集(DLL),並保留框架程序集的白名單。
  • 確定類型所在的命名空間,並排除框架。
+0

在使用Fluent NHibernate的評論中,「知名」結構的白名單是最好的方法。該清單足夠簡短易於理解,並且可能永遠不會改變。 – 2010-04-26 14:06:54

+0

同意,因爲你發現每一個導致崩潰,將其添加到白名單(或黑名單或任何你稱之爲),並繼續。該框架沒有太多的結構。 – stusmith 2010-04-26 14:26:05

+0

是的,但不幸的是這裏沒有列表。如果你錯過了一些東西,並在稍後使用這個結構,你將不知道爲什麼框架開始崩潰 – SztupY 2010-05-01 20:11:44

2

您可以檢查結構類型下的任何地方內系統命名空間下降。但是,這不是一個可靠的解決方案。

3

將上述意見納入一種推廣方法:

public static class ReflectionExtensions { 
     public static bool IsCustomValueType(this Type type) {    
       return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System."); 
     } 
    } 

應該工作

-1

你有與該類型那張價值?調用ToString方法並檢查返回的字符串是否以「{」開頭。

如果您沒有值,請檢查它是否具有無參數構造函數。如果它不是,它是一個構造函數。如果是,請使用Activator創建一個實例並再次調用ToString方法。

相關問題