作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设我有以下枚举:
[Flags]
enum IntFlags
{
A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
AAndB = A | B
}
我想构建一个辅助方法来设置如下标志:
private static IntFlags Set(IntFlags values, IntFlags target)
{
return target | values;
}
是否有任何灵活的方法来进行健全性检查?就像不可能设置枚举中不存在或不是现有值组合的值。
像下面这样的事情应该是不可能的:
IntFlags flags = 0;
flags = Set(0, flags);
flags = Set((IntFlags)int.MaxValue, flags);
flags = Set(~IntFlags.A, flags);
我想只是对现有值进行检查,例如:
private static IntFlags Set(IntFlags values, IntFlags target)
{
if (!Enum.GetValues(typeof(IntFlags)).Cast<IntFlags>().Contains(values))
throw new ArgumentException();
return target | values;
}
不会工作,因为设置值如
IntFlags flags = 0;
flags = Set(IntFlags.A | IntFlags.C, flags);
应该允许。
我认为这可能有效:
IntFlags Set(IntFlags values, IntFlags target)
{
int intValue;
if (int.TryParse(values.ToString(), out intValue))
{
throw new ArgumentException();
}
...
}
但这依赖于我在枚举上使用 Flags 属性这一事实。
编辑
我现在找到了 Enum.IsDefined() 方法。它与
配合得很好Assert.False(Enum.IsDefined(typeof(IntFlags), (IntFlags)int.MaxValue));
Assert.False(Enum.IsDefined(typeof(IntFlags), 0));
Assert.False(Enum.IsDefined(typeof(IntFlags), ~IntFlags.A));
但组合值不符合我的要求
Assert.True(Enum.IsDefined(typeof(IntFlags), IntFlags.A | IntFlags.C)); //fails
最佳答案
没有办法静态地禁止 Enum
的用户创建表示基础类型的任何值的枚举。正如问题中所示,您只能在运行时进行此类验证。
如果您只是在寻找一种足够简单的方法来在运行时验证特定枚举值是否是标志的有效组合,那么这是一个足够简单的检查,假设定义的枚举值实际上是 2 的递增幂.对于这样的枚举,所有有效值将从零变为比二的下一个最高幂小一,因此检查将变为:
if((int)values > 0 && (int)values >= 1 << 3))
throw new ArgumentException();
从技术上讲,您可以通过必须映射每个值来删除所有可能的未映射值,但这不是一个特别实用的解决方案。
如果其中任何一个都不是一个选项,您剩下的就是不使用 Enum
,而是使用具有您想要的确切语义的您自己的自定义类型:
public class IntFlags
{
public int Value { get; private set; }
private IntFlags(int value)
{
this.Value = value;
}
public static readonly IntFlags A = new IntFlags(1);
public static readonly IntFlags B = new IntFlags(2);
public static readonly IntFlags C = new IntFlags(4);
public static IntFlags operator |(IntFlags first, IntFlags second)
{
return new IntFlags(first.Value | second.Value);
}
public override bool Equals(object obj)
{
return Equals(obj as IntFlags);
}
public override bool Equals(IntFlags obj)
{
return obj != null && Value == obj.Value;
}
}
关于c# - 如何避免不可能的枚举值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25752963/
我是一名优秀的程序员,十分优秀!