我有一个像这样定义的标志枚举:
[Flags]
public enum MyEnum
{
None = 0x00,
Choice1 = 0x01,
Choice2 = 0x02,
Choice3 = 0x04,
Default = Choice1 | Choice2,
All = Default | Choice3
}
Run Code Online (Sandbox Code Playgroud)
我想要一种方法来打印出包含哪些标志MyEnum.Default.在这种情况下,我希望输出类似于"Choice1,Choice2".
简单打印的问题MyEnum.Default.ToString()是当我想要"Choice1,Choice2"时输出将是"默认".
这是一个选项,但如果我使用它,我每次更改枚举时都必须更新打印.
((StudyData.Choice1 & StudyData.Default) == StudyData.Choice1 ? StudyData.Choice1.ToString() : "") + ", " +
((StudyData.Choice2 & StudyData.Default) == StudyData.Choice2 ? StudyData.Choice2.ToString() : "") + ", " +
((StudyData.Choice3 & StudyData.Default) == StudyData.Choice3 ? StudyData.Choice3.ToString() : "")
Run Code Online (Sandbox Code Playgroud)
有没有人有更清洁的方式这样做?理想情况下,我想要一种打印出包含的标志的方法,MyEnum.Default而不必在每次添加新标志或更改默认值时更改打印代码.
谢谢!
Jef*_*ado 15
使用我在这里写的相关问题的扩展方法,这应该很简单:
var value = MyEnum.Default;
var str = String.Join(", ", value.GetIndividualFlags());
// "Choice1, Choice2"
Run Code Online (Sandbox Code Playgroud)
这是扩展方法:
static class EnumExtensions
{
public static IEnumerable<Enum> GetFlags(this Enum value)
{
return GetFlags(value, Enum.GetValues(value.GetType()).Cast<Enum>().ToArray());
}
public static IEnumerable<Enum> GetIndividualFlags(this Enum value)
{
return GetFlags(value, GetFlagValues(value.GetType()).ToArray());
}
private static IEnumerable<Enum> GetFlags(Enum value, Enum[] values)
{
ulong bits = Convert.ToUInt64(value);
List<Enum> results = new List<Enum>();
for (int i = values.Length - 1; i >= 0; i--)
{
ulong mask = Convert.ToUInt64(values[i]);
if (i == 0 && mask == 0L)
break;
if ((bits & mask) == mask)
{
results.Add(values[i]);
bits -= mask;
}
}
if (bits != 0L)
return Enumerable.Empty<Enum>();
if (Convert.ToUInt64(value) != 0L)
return results.Reverse<Enum>();
if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L)
return values.Take(1);
return Enumerable.Empty<Enum>();
}
private static IEnumerable<Enum> GetFlagValues(Type enumType)
{
ulong flag = 0x1;
foreach (var value in Enum.GetValues(enumType).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
if (bits == 0L)
//yield return value;
continue; // skip the zero value
while (flag < bits) flag <<= 1;
if (flag == bits)
yield return value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
用FlagsAttribute装饰枚举。它几乎可以完全满足您的要求:
[Flags]
public enum FooNum
{
foo = 0,
bar = 1,
lulz = 2,
borkbork = 4
}
FooNum f = FooNum.bar | FooNum.borkbork;
Debug.WriteLine(f.ToString());
Run Code Online (Sandbox Code Playgroud)
应该给你:
酒吧,博克博克