2012-09-07 127 views
10

這裏有很多關於將字符串轉換爲枚舉值的問題。一般來說,答案看起來this question類似的答案:Enum.Parse()爲什麼返回對象?

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true); 

雖然這是一個完全合理的答案,你可以寫簡化呼叫的方法,它並沒有回答爲什麼枚舉的問題。 Parse()返回一個object而不是適當的枚舉值。爲什麼我必須將它投射到StatusEnum


編輯:

基本上,問題是,爲什麼像枚舉類這不是一部分的功能?

public static T Parse<T>(string value) where T: struct 
    { 
     return (T)Enum.Parse(typeof (T), value); 
    } 

此功能工作得很好,完全符合您的期望。 StatusEnum e = Enum.Parse<StatusEnum>("Active");

+1

@ SpYk3HH - 枚舉不*有*值。他們*是*值。它們是碰巧對'.ToString()'有通常重載的值,但它們仍然只是值。 – Bobson

+2

.NET 4.0+已['Enum.TryParse '](http://msdn.microsoft.com/en-us/library/dd783499(V = VS.100)) –

+0

@ SpYk3HH枚舉類型的值是一些可能與某個枚舉類型的字段關聯的整數。整數的大小可能會有所不同。解析需要一些字符串並返回枚舉類型的盒裝實例。這可以拆箱或不拆箱。你的最後一句話也沒有意義。字符串和布爾值也有工作的屬性和方法。 – phoog

回答

10

它這樣做是因爲

  1. 它早泛型和(即使它沒有:)
  2. 泛型約束不能枚舉(在主流的.NET語言)

因此,Object僅僅是永遠對任何類型的enum工作類型。

通過返回對象,API是至少功能性的,即使需要的鑄造。

+1

儘管你不能說'where t:Enum',你可以說'where t:struct'並且至少消除了引用類型,或者沒有約束並且避免了cast/typeof。 – Guvante

+0

它早於仿製藥的事實並不是一種探索。將上面編輯的函數添加爲舊式'Enum.Parse()'的重載是一個不會改變的改變。 – Bobson

+0

@Reed - 通過你的邏輯來思考它,Enum.TryParse ()也不應該存在,但它確實存在。 – Bobson

1

實際類型的對象確實是StatusEnum。編寫代碼時,編譯器Enum.Parse不知道該方法寫入時該運行時對象的內容。直到實際調用該方法後才能知道它。然而

3

的TryParse不支持類型參數:

Enum.TryParse<FooEnum>(name, true, out ret);

因此,如果您指定的超時值RET爲FooEnum ret;,你不會需要將其轉換爲FooEnum之後;它會馬上成爲正確的類型。

+0

這是真的,但你現在需要兩行代碼。可能三個。一個宣佈'ret',這個和一個使用它,否則你可能不需要它。因此提出了爲什麼有一個通用形式的'TryParse()'而不是'Parse()'的通用形式的問題。 – Bobson

+0

它可能只是被忽略了。儘管你可以很容易地將自己的泛型重載作爲擴展方法。 – aevitas

+0

其實你不行。你不能擴展'Enum',因爲它是一個靜態類。所以你會調用'EnumExtensions.Parse()'(或者你稱之爲你的類),並且作爲擴展方法沒有任何好處。 – Bobson

相關問題