泛型扩展方法来查看枚举是否包含一个标志 [英] Generic extension method to see if an enum contains a flag
问题描述
考虑到这一点:
[Flags]
public enum MyEnum {
One = 1,
Two = 2,
Four = 4,
Eight = 8
}
public static class FlagsHelper
{
public static bool包含(这个MyEnum键,MyEnum标志)
{
return(keys& flag)!= 0;
}
}
是否可以编写一个通用版的Contains将适用于任何枚举
而不仅仅是 MyEnum
?
编辑
阅读您的答案后,这将是我的版本:
public static bool包含(此枚举键,枚举标志)
{
ulong keysVal = Convert.ToUInt64(keys);
ulong flagVal = Convert.ToUInt64(flag);
return(keysVal& flagVal)== flagVal;
}
刚刚实现是一个坏主意,检查我正在检查的方式( return(keys& flag)!= 0;
),因为标志
参数实际上可能是几个标志和常识只有当键
包含所有这些键,事情才会返回true。此外,我不会检查null值,甚至确保它们是相同的类型。我可能希望使用不同的类型。
&安培; Google搜索,并通过使用反射器查看MS对于.NET 4 HasFlags方法的作用。
public static class EnumExt
{
///< summary>
///检查一个标志枚举是否设置了一个特定的标志。
///< / summary>
///< param name =variable>要检查的枚举枚举< / param>
///< param name =value>要检查的标志< / param>
///< returns>< / returns>
public static bool HasFlag(这个枚举变量,枚举值)
{
if(variable == null)
return false;
if(value == null)
throw new ArgumentNullException(value);
//不如.NET 4版本的这个函数,但应该是够好的
if(!Enum.IsDefined(variable.GetType(),value))
{
throw new ArgumentException(string.Format(
枚举类型不匹配。该标志的类型为{0},期待'{1}'。,
值.GetType(),variable.GetType()));
}
ulong num = Convert.ToUInt64(value);
return((Convert.ToUInt64(variable)& num)== num);
}
}
注意: / p>
- 此处理空值
- 类型检查
- 转换到一个ulong,并且可以处理任何正的枚举值。反对使用负标志枚举的 Microsoft注意事项:
如果您将负数定义为枚举常量,请谨慎使用,因为许多标志位可能设置为1,这可能会使您的代码变得混乱并鼓励编码错误。
Considering this:
[Flags]
public enum MyEnum {
One = 1,
Two = 2,
Four = 4,
Eight = 8
}
public static class FlagsHelper
{
public static bool Contains(this MyEnum keys, MyEnum flag)
{
return (keys & flag) != 0;
}
}
Is it possible to write a generic version of Contains that would work for any enum
and not just MyEnum
?
Edit:
This would be my version after reading your answers:
public static bool Contains(this Enum keys, Enum flag)
{
ulong keysVal = Convert.ToUInt64(keys);
ulong flagVal = Convert.ToUInt64(flag);
return (keysVal & flagVal) == flagVal;
}
Just realized is a bad idea to check the way I was checking (return (keys & flag) != 0;
), because the flag
parameter might be actually several flags and the common sense thing to do is return true only if keys
contains all of them. Also, I wouldn't check for null values or even make sure they are the same type. I might want to use different types.
I based this method off of a bunch of SO & Google searches, and a by using reflector to see what MS did for the .NET 4 HasFlags method.
public static class EnumExt
{
/// <summary>
/// Check to see if a flags enumeration has a specific flag set.
/// </summary>
/// <param name="variable">Flags enumeration to check</param>
/// <param name="value">Flag to check for</param>
/// <returns></returns>
public static bool HasFlag(this Enum variable, Enum value)
{
if (variable == null)
return false;
if (value == null)
throw new ArgumentNullException("value");
// Not as good as the .NET 4 version of this function, but should be good enough
if (!Enum.IsDefined(variable.GetType(), value))
{
throw new ArgumentException(string.Format(
"Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.",
value.GetType(), variable.GetType()));
}
ulong num = Convert.ToUInt64(value);
return ((Convert.ToUInt64(variable) & num) == num);
}
}
Notes:
- This handles nulls
- Does type checking
- Converts to a ulong, and can handle any positive enum value. Microsoft cautions against the use of negative flags enumerations anyway:
Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors.
这篇关于泛型扩展方法来查看枚举是否包含一个标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!