2016-01-31 32 views
7

C#.NET 4.5中,Windows 10,我有以下枚舉:C#Enum.TryParse解析無效數字串

private enum Enums 
{ 
    A=1, B=2, C=3 
} 

,並將該軟件以一種非常奇怪的方式表現:

public static void Main() 
{ 
    Enums e; 
    if (Enum.TryParse("12", out e)) 
    { 
     Console.WriteLine("Parsed {0}", e); 
    } 
    else 
    { 
     Console.Write("Not parsed"); 
    } 
    Console.ReadLine(); 
} 

我會期望TryParse方法的結果是錯誤的,但令我驚訝的是,控制檯顯示「Parsed 12」。 在Watch窗口中,它甚至顯示值爲「12」,並且它是Enums類型!

對於我嘗試過的任何數字字符串(例如「540」),但對於包含字母(「A12」,「12A」)的字符串不適用。

我可以很容易地克服這個問題,首先檢查它是否只是數字字符串,但爲什麼這是行爲? 是否由設計?

謝謝! 伊

+1

是的,它是由設計。如果一個值上的'.ToString()'可以返回一個特定的字符串,並且所討論的類型有一個'.Parse()'方法,那麼parse方法應該接受該字符串,這是一個好主意。由於枚舉可以包含「未知」值(例如,在枚舉中沒有名稱的值),'.ToString()'會將這些值作爲字符串中的數字返回,所以它遵循'.Parse() '應該接受一個只包含整數的字符串。所以是的,這是設計。你可能不同意這個決定,但它是這樣的。 –

回答

6

在內部,枚舉被存儲爲整數爲什麼的TryParse爲被傳遞。

整數至於爲什麼任何整數工作,它的設計返回true這是可能的。從MSDN(重點煤礦):

此方法返回時,結果包含類型TEnum ,其值由值,如果解析操作成功表示的對象。 如果解析操作失敗,結果將包含默認值 基本類型的TEnum。 請注意,此值不一定是 TEnum枚舉的成員。此參數未經初始化傳遞。

+3

謝謝! 我沒有找對地方.. 而且,顯然是從MSDN: 如果這種行爲是不可取的,調用IsDefined方法,以確保一個整數的特定字符串表示實際上是TEnum的成員。 –

+0

不客氣。是的,如果有可能傳入非成員整數,使用IsDefined將會有所幫助。您可以創建一個擴展方法,在解析後處理您的IsDefined'檢查,以便您可以使用該方法而不是默認的'TryParse'。 – keyboardP

2

枚舉類型可以保持其基本類型的任何值,因此存儲在Enums類型的在你的情況下的變量12的值的變量或字段是完全合法的:

var e = (Enums) 12; 
var i = (int) e; // i is 12 

因此,Enum.TryParse必須能夠解析類型爲int(或枚舉中使用的任何基礎整數類型)的任何值。

如果您想拒絕枚舉中沒有表示的值,請使用Enum.IsDefined進行檢查。