值是一个枚举和-1?

ygo*_*goe 3 .net c# enums

对于视图模型验证,我需要确定一个值(我只有一个对象接口)是一个枚举并且数值为-1.

我试过这个:

// object value;
if (value?.GetType().IsEnum == true && (int)value == -1) return null;
Run Code Online (Sandbox Code Playgroud)

它应该与我的模型枚举一起使用,这些枚举主要基于int.

但是当值是一个Visibility枚举(它恰好也在视图模型类中并且应该被忽略以进行验证)时它会失败,而这个枚举基于byte代替int而且似乎不能转换为int.我可以做更多的测试,但它不应该太慢.

对此有一个很好的简单解决方案吗?也许是Enum班上的一些测试方法还是什么?

Ren*_*ogt 6

您可以使用以下方法检查基础类型GetEnumUnderlyingType():

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

因为一个byte永远不会-1,你不需要检查它.但是你也可能需要延长对long枚举的检查.


更新:

我只是尝试了一下,发现它Convert.ToInt32()也解决了你的问题:

if (value?.GetType().IsEnum == true && 
    Convert.ToInt64(value) == -1)
    return null;
Run Code Online (Sandbox Code Playgroud)

这似乎更清晰,也适用于所有可能的底层类型.


另一个更新:不幸的是,上面的解决方案并不像我想象的那么干净.即使Convert.ToInt64()解决了long值太大的问题Int32,但如果你通过例如a它会抛出ulong.MaxValue.

因此,您必须为所有可能的枚举基类型选择足够大的类型:

if (value?.GetType().IsEnum == true && 
    Convert.ToDecimal(value) == -1)
    return null;
Run Code Online (Sandbox Code Playgroud)

使用Convert.ToDecimal()它会传递到目前为止出现的所有测试用例.

  • 在[enum(C#参考)](https://msdn.microsoft.com/en-us/library/sbbt4032.aspx)之后考虑其他人:_枚举的批准类型是`byte`,`sbyte `,`short`,`ushort`,`int`,`uint`,`long`或`ulong`._ (3认同)
  • @gaa但异常是昂贵的,所以我选择`Convert.ToDecimal()`来避免这个问题. (2认同)