检查枚举是否包含多个标志
Check if an enum contains more than one flag
我正在尝试检查 "enum instance" 是否包含多个标志。
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
var multiState = Foo.Bar | Foo.Far;
MoreThanOneFlag(multiState); // True
var singleState = Foo.Bar;
MoreThanOneFlag(singleState); // False
此外,我真的不想使用类似下面的东西:
var state = Foo.Bar | Foo.Far;
Console.WriteLine(state.ToString().Count(x => x == ',') > 0); // True
注意,我不关心 "instance" 包含哪些标志,我只想知道是否有多个标志。
您可以对 enum
值使用二进制对数函数,然后检查结果是否为整数。
下面的例子定义了扩展方法助手,returns true
当设置了多个标志时:
HelperExtenxsions.cs
public static class HelperExtenxsions
{
public static bool HasMultipleFlags(this IConvertible enumValue)
{
return Math.Log(enumValue.ToInt32(CultureInfo.InvariantCulture.NumberFormat), 2) % 1 != 0;
}
}
Foo.cs
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
Program.cs
public static void Main()
{
var enumValue = Foo.Bar | Foo.Far;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'True'
enumValue = Foo.Bar;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'False'
}
您可以在 conjunction 和 Enum.HasFlag(Enum)
中使用 Enum.GetValues
来迭代每个 constant 并确定是否位字段在当前实例中设置,return 它的计数。
[Flags]
public enum Foo
{
One = 1,
Two = 2,
Four = 4,
Eight = 8
}
var state1 = Foo.One;
var state2 = Foo.Two;//
var state3 = Foo.One | Foo.Two;
var state4 = Foo.Two | Foo.Four;
Console.WriteLine(MoreThanOneFlag(state1));//false
Console.WriteLine(MoreThanOneFlag(state2));//false
Console.WriteLine(MoreThanOneFlag(state3));//true
Console.WriteLine(MoreThanOneFlag(state4));// true
private static bool MoreThanOneFlag<TEnum>(TEnum state) where TEnum : Enum
{
var names = Enum.GetValues(typeof(TEnum));
var Flagcounter = names.OfType<TEnum>().Where(x=>state.HasFlag((TEnum)x)).Count();
return Flagcounter > 1 ? true : false;
}
注意: 虽然如果您的应用程序需要性能,Enum.HasFlags
可能不是合适的解决方案,但 reliable, clean, and makes the code very obvious and expressive
参考:
I am trying to check if an "enum instance" contains more than one flag.
I do not care which Flags the "instance" contains, I just want to know if there are more than one
Additionally I really don't wanna use something like the following:
var state = Foo.Bar | Foo.Far;
Console.WriteLine(state.ToString().Count(x => x == ',') > 0); // True
有很多不同的方法可以完成你想要的,我建议做一点(按位)检查:
public static bool MoreThanOneFlag<TValue>(TValue flag) where TValue : Enum => (Convert.ToInt32(flag) & (Convert.ToInt32(flag) - 1)) != 0;
在上面的代码块中,我们通过使用 flag & (flag-1)) != 0
(& 运算符)检查 flag
是否不是二的幂 其操作数的按位逻辑与。如果只设置了一个标志,那么我们假设该值将是 2 的幂,否则它不是 2 的幂。
或者,如果您不需要辅助函数,只需在任何地方执行该检查即可:
bool value = (multiState & (multiState -1)) != 0;
有关按位的更多信息,please check out 此处有更多信息。
参考文献:
我正在尝试检查 "enum instance" 是否包含多个标志。
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
var multiState = Foo.Bar | Foo.Far;
MoreThanOneFlag(multiState); // True
var singleState = Foo.Bar;
MoreThanOneFlag(singleState); // False
此外,我真的不想使用类似下面的东西:
var state = Foo.Bar | Foo.Far;
Console.WriteLine(state.ToString().Count(x => x == ',') > 0); // True
注意,我不关心 "instance" 包含哪些标志,我只想知道是否有多个标志。
您可以对 enum
值使用二进制对数函数,然后检查结果是否为整数。
下面的例子定义了扩展方法助手,returns true
当设置了多个标志时:
HelperExtenxsions.cs
public static class HelperExtenxsions
{
public static bool HasMultipleFlags(this IConvertible enumValue)
{
return Math.Log(enumValue.ToInt32(CultureInfo.InvariantCulture.NumberFormat), 2) % 1 != 0;
}
}
Foo.cs
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
Program.cs
public static void Main()
{
var enumValue = Foo.Bar | Foo.Far;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'True'
enumValue = Foo.Bar;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'False'
}
您可以在 conjunction 和 Enum.HasFlag(Enum)
中使用 Enum.GetValues
来迭代每个 constant 并确定是否位字段在当前实例中设置,return 它的计数。
[Flags]
public enum Foo
{
One = 1,
Two = 2,
Four = 4,
Eight = 8
}
var state1 = Foo.One;
var state2 = Foo.Two;//
var state3 = Foo.One | Foo.Two;
var state4 = Foo.Two | Foo.Four;
Console.WriteLine(MoreThanOneFlag(state1));//false
Console.WriteLine(MoreThanOneFlag(state2));//false
Console.WriteLine(MoreThanOneFlag(state3));//true
Console.WriteLine(MoreThanOneFlag(state4));// true
private static bool MoreThanOneFlag<TEnum>(TEnum state) where TEnum : Enum
{
var names = Enum.GetValues(typeof(TEnum));
var Flagcounter = names.OfType<TEnum>().Where(x=>state.HasFlag((TEnum)x)).Count();
return Flagcounter > 1 ? true : false;
}
注意: 虽然如果您的应用程序需要性能,Enum.HasFlags
可能不是合适的解决方案,但 reliable, clean, and makes the code very obvious and expressive
参考:
I am trying to check if an "enum instance" contains more than one flag. I do not care which Flags the "instance" contains, I just want to know if there are more than one
Additionally I really don't wanna use something like the following:
var state = Foo.Bar | Foo.Far;
Console.WriteLine(state.ToString().Count(x => x == ',') > 0); // True
有很多不同的方法可以完成你想要的,我建议做一点(按位)检查:
public static bool MoreThanOneFlag<TValue>(TValue flag) where TValue : Enum => (Convert.ToInt32(flag) & (Convert.ToInt32(flag) - 1)) != 0;
在上面的代码块中,我们通过使用 flag & (flag-1)) != 0
(& 运算符)检查 flag
是否不是二的幂 其操作数的按位逻辑与。如果只设置了一个标志,那么我们假设该值将是 2 的幂,否则它不是 2 的幂。
或者,如果您不需要辅助函数,只需在任何地方执行该检查即可:
bool value = (multiState & (multiState -1)) != 0;
有关按位的更多信息,please check out 此处有更多信息。
参考文献: