Dot-Net
.NET:為什麼不檢查列舉的範圍/值?
這一直困擾著我。也許對 .NET 內部有一些核心知識的人可以向我解釋一下。
假設我定義一個列舉如下:
public enum Foo { Eenie = 1, Meenie = 2, Miney = 3, Moe = 4 }現在,還假設在我的程式碼中的某處,我有以下程式碼:
int bar = (Foo)5;這將編譯得很好,並且不會引發任何異常,即使值 5 顯然不是
Foo.或者,考慮以下幾點:
public void ProcessFoo(Foo theFoo) { // Do processing } public static void Main() { ProcessFoo((Foo)5); }同樣,也不例外。
在我看來,這應該會導致類型不匹配異常,因為 5 不是
Foo. 但設計師選擇不這樣做。現在,我編寫了一個擴展方法,可以驗證是否是這種情況,呼叫它來確保是這種情況並沒有什麼大不了的,但我必須使用反射來做到這一點(所有的性能損失等等)。
再說一遍,有什麼令人信服的理由可能促使決定不檢查列舉?
作為參考,來自Enum 類的 MSDN 文件:
當您定義將列舉常量作為值的方法或屬性時,請考慮驗證該值。原因是您可以將數值轉換為列舉類型,即使該數值未在列舉中定義。
問題是性能。對普通列舉(例如 Color)進行檢查列舉非常簡單
enum Color { Red, Blue }但問題在於用作位標誌的列舉。
enum Property { IsFirst = 0x1, IsDefault = 0x2, IsLastAccessed = 0x4 }必須對轉換為 Enum 值的每個整數進行按位檢查被認為過於昂貴。因此,輕鬆轉換為列舉值。
範圍檢查可能會產生不必要的成本。因此,不隱式執行它是合理的。如前所述,
[Flags]要求不進行此類檢查。如果執行時會檢查是否存在[Flags],則每次執行轉換時仍會導致執行時損失。解決這個問題的唯一方法是讓編譯器知道該
[Flags]屬性。我想這樣做並不是為了減少硬編碼到編譯器中的執行時知識量。