想要定義一個表示數(shù)據(jù)庫主鍵編號范圍的枚舉:
/// <summary> /// 編號范圍枚舉 /// </summary> public enum IDRangeType : Int64 { /// <summary> /// 1到2的32次方 /// </summary> [Descr但是上面這種聲明直接導致編譯錯誤:應輸入類型 byte、sbyte、short、ushort、int、uint、long 或 ulong
也就是說,枚舉的基礎類型只能為8種數(shù)字類型: byte、sbyte、short、ushort、int、uint、long 或 ulong。聲明為其他類型如Int16、Int32、Int64等都不行。
按照VS編譯提示,將Int64改為long,果然通過,真是奇哉怪也。
我們平時理解的Int64和long其實在MS .Net Framework中是沒有區(qū)別的,long只是Int64的一個別名而已(而java的基元值類型的包裝類都是引用類型),而且Framework編程規(guī)范里還明確說推薦使用Int64,這樣可以保證跨語言或者跨平臺代碼移植方便。但是在枚舉聲明這里,只能使用別名。
順帶再提一下.NET Framework中非常特殊的一個類型System.Enum,它是個引用類型,F(xiàn)ramework中將System.Enum定義為一個抽象類,但是它又繼承自System.ValueType。
通過類型判斷,卻又發(fā)現(xiàn)它不是ValueType,而且也不是枚舉:
var num = new Int32(); Console.WriteLine(num is ValueType); //True Console.WriteLine(num.GetType().IsValueType); //True var type = typeof(System.Enum); Console.WriteLine(type.IsValueType); //False ??? Console.WriteLine(type.IsEnum); //False ???C#語言特性中有很多特例存在,System.Enum即為一例。
2、web服務的客戶端代理和服務端的枚舉數(shù)值定義不一致
還以上面的枚舉作為示例,我們要在一個標識為WebMethod的web服務方法中使用這個枚舉,新建一個web服務并部署好以后供客戶端調(diào)用。
通過WSDL工具,直接將這個web服務生成保存為本地代理類,然后查看代理類源代碼,客戶端代理類生成的枚舉IDRangeType竟然變成:
public enum IDRangeType : long { Between1ToPowerOf32, BetweenPowerOf32ToPowerOf40, Bigger, }客戶端生成的枚舉,沒有把服務端枚舉定義中顯式定義的數(shù)值帶過來。對于IDRangeType這種定義枚舉就是要使用枚舉的數(shù)值而言,簡直太出乎人的意料之外。
然后想到可能是序列化和反序列化的問題,嘗試著給枚舉屬性分別加上特性DataMember和EnumMember,問題依舊。但在WCF試驗中發(fā)現(xiàn)一切正常,打開WCF生成的客戶端代理類,枚舉數(shù)值的定義和服務端沒什么變化。
后來想想又搞不明白,枚舉既然是繼承自基元值類型,那么值類型怎么序列化,枚舉也應該像基元值類型一樣序列化才對,而且一直說服務分享 Schema(for structures) 和 Contract(for behaviors), 而不是 Class,難道枚舉不是Schema和Contract的一部分,或者是SOAP的.NET實現(xiàn)不支持枚舉?
試驗多次久久不能解決問題,最后搜索一下.net web服務和枚舉這兩個關(guān)鍵字,發(fā)現(xiàn)果然很早就有一篇流傳甚廣的Web Services and C# Enums文章講到“Numeric Values Are Not PReserved”這個事情。文章還有提到,在web服務中,F(xiàn)lag標記下的枚舉在客戶端生成的時候數(shù)值改變,很容易導致災難后果(This can lead to disastrous consequences)。
通過這個問題,讓我深深意識到服務端和客戶端生成代碼的差異,不同環(huán)境不同應用場景下,有些特殊情況很容易偏離習慣認知和主觀判斷,必須多嘗試實踐才能出真知。
參考:
http://ikriv.com/dev/dotnet/webservices_and_enums.html
http://msdn.microsoft.com/zh-cn/library/System.Web.Services(v=vs.110).aspx
http://msdn.microsoft.com/zh-cn/library/sbbt4032.aspx
http://msdn.microsoft.com/zh-cn/library/aa347875(v=vs.110).aspx
新聞熱點
疑難解答