2017-03-09 78 views
3

對於視圖模型驗證,我需要確定一個值,其中我只有一個對象接口,是一個枚舉並具有數值-1。值是一個枚舉和-1?

我嘗試這樣做:

// object value; 
if (value?.GetType().IsEnum == true && (int)value == -1) return null; 

應該與大多基於int我的模型枚舉工作。

但當值是Visibility枚舉(這正好也是在視圖模型類,並應確認被忽略),這是基於byte而不是int,這似乎不被強制轉換爲int失敗。我可以做更多的測試,但不應該太慢。

有沒有一個很好的簡單解決方案呢?也許在Enum類中有些測試方法或者什麼?

+1

顯示的枚舉代碼。 – HimBromBeere

+2

字節不能等於-1。 – mukh1n

+0

也許你需要將枚舉基於'sbyte'而不是'byte'。 –

回答

6

你可以用GetEnumUnderlyingType()檢查基本類型:

Type t = value?.GetType(); 
if (t?.IsEnum == true && 
    t?.GetEnumUnderlyingType() == typeof(int) && 
    (int)value == -1) 
    return null; 

由於byte永遠不能-1,你並不需要檢查它。但是您也可能需要延長long枚舉的支票。


UPDATE

我只是想繞了一點,發現Convert.ToInt32()也解決了你的問題:

if (value?.GetType().IsEnum == true && 
    Convert.ToInt64(value) == -1) 
    return null; 

這似乎更清潔,也適用於所有可能的基礎類型。


另一個更新:不幸的是,上面的解決方案並不像我想的那麼幹淨。即使Convert.ToInt64()解決了long值太大的問題Int32,但它會拋出,如果你通過例如ulong.MaxValue

所以,你必須選擇一個類型,它是足夠大,爲所有可能的枚舉基本類型:

if (value?.GetType().IsEnum == true && 
    Convert.ToDecimal(value) == -1) 
    return null; 

使用Convert.ToDecimal()這通過所有想出了迄今爲止測試用例。

+3

取爲好,之後[枚舉(C#參考)](https://msdn.microsoft.com/en-us/library/sbbt4032.aspx):_The批准類型枚舉是'byte','sbyte','short','ushort','int','uint','long',或'ulong'._ – gaa

+0

在第二個例子中,如果發生什麼'枚舉MyEnum:long {MaxValue = long.MaxValue}}',然後'value = MyEnum.MaxValue'? :-) – xanatos

+0

@xanatos該死的權利,'Convert.ToInt64()'可以解決這個問題,但會拋出'ulong.MaxValue' ...我不斷嘗試... –

0

另外,如果該值是有效的枚舉,則可以考慮使用Enum.IsDefined Method (Type, Object)來驗證。

那當然不包括「檢查它是否爲-1」部分。

Enum.IsDefined方法(Type,對象)

是否與規定值的恆定存在於指定的枚舉 返回一個指示。命名空間:系統程序集:mscorlib (在mscorlib中。DLL)

[ComVisibleAttribute(true)] public static bool IsDefined(Type enumType, object value) 

參數

enumTypeTypeSystem.Type 枚舉類型。
valueTypeSystem.Object enumType中常量的值或名稱。

返回值

TypeSystem.Boolean變得true如果在enumType恆定具有 值等於值;否則,false

例外

ArgumentNullException' enumType or value is null. ArgumentException` enumType不是枚舉。 - 或者 - 值的類型是枚舉,但它不是enumType類型的枚舉。 - 或者 - 值的類型不是enumType的基礎類型。

InvalidOperationException值不是類型SByte,Int16,Int32,Int64,Byte,UInt16,UInt32,UInt64或String。

備註

值參數可以是任何以下的:

  • 類型enumType的任何成員。
  • 一個變量,其值是enumType類型的枚舉成員。
  • 枚舉成員的名稱的字符串表示形式。字符串中的 字符必須與枚舉 成員名稱具有相同的大小寫。
  • enumType的基礎類型的值。

如果enumType常數定義一組比特字段和值 的包含值,名稱,或底層的多位 字段的值,則IsDefined方法返回false。換句話說,對於 定義一組位字段的枚舉,該方法僅確定 是否一個位字段屬於枚舉。至 確定是否在使用FlagsAttribute屬性標記的枚舉類型 中設置了多個位字段,則可以調用 HasFlag方法。

0

,你可以:

if (value != null) 
{ 
    var type = value.GetType(); 

    if (type.IsEnum && object.Equals(Enum.ToObject(type, -1), value)) 
    { 
     return null; 
    } 
} 

我不得不這樣做在多行 「緩存」 的GetType()。訣竅是使用Enum.ToObject()將「-1」投射到當前的Enum類型。

注意,鑄造將產生 「奇怪」 的結果:

public enum TestEnum : ulong 
{ 
    ValueMax = ulong.MaxValue 
} 

在這種情況下,TestEnum.ValueMaxreturn null。這將發生在所有的無符號類型上。

0

byte可強制轉換爲int,如果它不與object

byte b = 1; 
int i = (int)b; //works good 
int f = (int)(object)b; //fails 

盒裝所以,你可以使用Convert.ToInt32方法,如勒內·沃格特提出您的變量轉換爲int,或將其轉換爲dynamic代替鑄造int

if (value?.GetType().IsEnum == true && (dynamic)value == -1) return null; 

儘管隨着dynamic操作是相當緩慢的。在我看來,與Convert.ToInt32的靈魂是最清潔和高效的。這個答案只是想指出,爲什麼你不能投的objectint,並提出一個dynamic版本演員。

相關問題