考虑我有这种扩展方法:
public static bool HasAnyFlagInCommon(this System.Enum type, Enum value)
{
var flags = value.ToString().Split(new string[] { ", " },
StringSplitOptions.None);
foreach (var flag in flags)
{
if (type.ToString() == flag)
return true;
}
return false;
}
以下情况:
[Flags]
enum Bla
{
A = 0,
B = 1,
C = 2,
D = 4
}
Bla foo = Bla.A | Bla.B;
Bla bar = Bla.A;
bar.HasAnyFlagInCommon(foo); //returns true
我想检查foo是否有任何与bar相同的标志,但是在扩展方法中必须有更好的方法来实现这种行为。
我也尝试过这样,但总是返回true:
public static bool HasAnyFlagInCommon(this System.Enum type, Enum value)
{
var flags = Enum.GetValues(value.GetType()).Cast<Enum>()
.Where(item => value.HasFlag(item));
foreach (var flag in flags)
{
if (type == flag)
return true;
}
return false;
}
答案 0 :(得分:6)
您可以简单地将Enum值转换为 ulong (以考虑基础类型不是 int 的默认值的可能性)。如果结果!= 0,则至少设置了一个标志。
ulong theValue = (ulong)value;
return (theValue != 0);
请记住,在一天结束时,枚举由byte,sbyte,short,ushort,int,uint,long或ulong中的一个支持。
http://msdn.microsoft.com/en-us/library/sbbt4032.aspx
正在设置的标志与在后备类型中打开的相应位相同。如果所有位都关闭,上面的 ulong 将只为0。
答案 1 :(得分:2)
像
这样的东西public static bool HasAnyFlagInCommon(this System.Enum type, Enum value)
{
return (((long)type) & ((long)value)) != 0;
}
对于在两个枚举中设置的任何位,&
都会给1
,所以如果有任何这样的位,则结果为非零。
(我已经使用了long
,希望它适用于enum的任何类型; int
在你的情况下应该没问题。)
答案 2 :(得分:1)
我们有一个扩展方法,该扩展方法基于以下网站中描述的 Has()扩展方法:http://somewebguy.wordpress.com/2010/02/23/enumeration-extensions-2。它应该比转换成字符串更快,但是我还没有检查性能。相关子集为:
/// <summary>
/// Checks if an enumerated type contains a value
/// </summary>
public static bool Has<T>(this Enum value, T check) {
Type type = value.GetType();
//determine the values
object result = value;
_Value parsed = new _Value(check, type);
if (parsed.Signed is long) {
return (Convert.ToInt64(value)& (long)parsed.Signed) == (long)parsed.Signed;
}
else if (parsed.Unsigned is ulong) {
return (Convert.ToUInt64(value) & (ulong)parsed.Unsigned) == (ulong)parsed.Unsigned;
}
else {
return false;
}
}
//class to simplfy narrowing values between
//a ulong and long since either value should
//cover any lesser value
private class _Value {
//cached comparisons for tye to use
private static Type _UInt64 = typeof(ulong);
private static Type _UInt32 = typeof(long);
public long? Signed;
public ulong? Unsigned;
public _Value(object value, Type type) {
//make sure it is even an enum to work with
if (!type.IsEnum) {
throw new ArgumentException("Value provided is not an enumerated type!");
}
//then check for the enumerated value
Type compare = Enum.GetUnderlyingType(type);
//if this is an unsigned long then the only
//value that can hold it would be a ulong
if (compare.Equals(_Value._UInt32) || compare.Equals(_Value._UInt64)) {
this.Unsigned = Convert.ToUInt64(value);
}
//otherwise, a long should cover anything else
else {
this.Signed = Convert.ToInt64(value);
}
}
}