C# Flags - 获取可以存在给定标志的所有可能组合
C# Flags - Getting all possible combinations where a given flag can be present
考虑以下枚举:
Enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
现在假设我们想要找到所有可能的标志组合,例如 Dog 处于活动状态。
我分为以下方法来做到这一点:
public static int[] testss(int value)
{
var animalTypes = (AnimalType)value;
List<int> possibleValues = new List<int>();
possibleValues.Add(value);
int totalEnumValues = Enum.GetNames(typeof(AnimalType)).Length;
List<int> helper = new List<int>();
int cnt = 0;
for (int i = 1; i < totalEnumValues; i++)
{
foreach (Enum val in Enum.GetValues(animalTypes.GetType()))
{
if (cnt >= i)
break;
if (i == 1)
{
if ((AnimalType)val != (AnimalType)value)
{
possibleValues.Add((int)(AnimalType)val + value);
}
}
else
{
if ((AnimalType)val != (AnimalType)value && (cnt < i))
{
helper.Add((int)(AnimalType)val);
cnt += 1;
}
}
}
if (cnt > 0)
{
possibleValues.Add(helper.Sum() + value);
helper = new List<int>();
cnt = 0;
}
}
return possibleValues.ToArray();
}
此方法将构建一个数组,其中包含所有可能的数字表示形式,其中包含作为输入的给定标志。
它仅部分起作用,例如,如果您针对 Dog (1) 对其进行测试,您会发现 possibleValues 数组中缺少 2 个值。
你能帮我看看哪里做错了吗?
您可以使用 [Flags]
枚举属性,然后是扩展方法。像这样:
[Flags]
enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
static class Program
{
static void Main(string[] args)
{
var test = AnimalType.Dog.AllContaining();
}
public static int[] AllContaining(this AnimalType thisAnimal)
{
List<int> retVal = new List<int>();
var possibleEnums = Enum.GetValues(typeof(AnimalType)).Length;
var maxValue = (int)Math.Pow(2, possibleEnums);
for (int i = 0; i < maxValue; i++)
{
if (((AnimalType)i).HasFlag(thisAnimal))
{
retVal.Add(i);
}
}
return retVal.ToArray();
}
}
它遍历枚举的所有可能的整数值,并查看所提供动物的 'flag' 是否存在。如果是,它会添加到 return 数组。
假设枚举值不多,你可以试试:
private static void Main(string[] args)
{
var type = AnimalType.Wolf;
foreach (var x in GetAllPossibleCombinationWith(type))
{
Console.WriteLine(x);
}
Console.ReadLine();
}
public static IEnumerable<AnimalType> GetAllPossibleCombinationWith(AnimalType type) // Bird
{
var maxValue = Enum.GetValues(typeof(AnimalType)).Cast<int>().Max();
var combinationValue =2* maxValue - 1;
for (int i = 0; i < combinationValue; i++)
{
var val = (AnimalType) i;
if ((val & type) == type) yield return val;
}
}
[Flags]
public enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8,
Fish = 16
}
它假定标志值中没有 "hole"。
考虑以下枚举:
Enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
现在假设我们想要找到所有可能的标志组合,例如 Dog 处于活动状态。
我分为以下方法来做到这一点:
public static int[] testss(int value)
{
var animalTypes = (AnimalType)value;
List<int> possibleValues = new List<int>();
possibleValues.Add(value);
int totalEnumValues = Enum.GetNames(typeof(AnimalType)).Length;
List<int> helper = new List<int>();
int cnt = 0;
for (int i = 1; i < totalEnumValues; i++)
{
foreach (Enum val in Enum.GetValues(animalTypes.GetType()))
{
if (cnt >= i)
break;
if (i == 1)
{
if ((AnimalType)val != (AnimalType)value)
{
possibleValues.Add((int)(AnimalType)val + value);
}
}
else
{
if ((AnimalType)val != (AnimalType)value && (cnt < i))
{
helper.Add((int)(AnimalType)val);
cnt += 1;
}
}
}
if (cnt > 0)
{
possibleValues.Add(helper.Sum() + value);
helper = new List<int>();
cnt = 0;
}
}
return possibleValues.ToArray();
}
此方法将构建一个数组,其中包含所有可能的数字表示形式,其中包含作为输入的给定标志。
它仅部分起作用,例如,如果您针对 Dog (1) 对其进行测试,您会发现 possibleValues 数组中缺少 2 个值。
你能帮我看看哪里做错了吗?
您可以使用 [Flags]
枚举属性,然后是扩展方法。像这样:
[Flags]
enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
static class Program
{
static void Main(string[] args)
{
var test = AnimalType.Dog.AllContaining();
}
public static int[] AllContaining(this AnimalType thisAnimal)
{
List<int> retVal = new List<int>();
var possibleEnums = Enum.GetValues(typeof(AnimalType)).Length;
var maxValue = (int)Math.Pow(2, possibleEnums);
for (int i = 0; i < maxValue; i++)
{
if (((AnimalType)i).HasFlag(thisAnimal))
{
retVal.Add(i);
}
}
return retVal.ToArray();
}
}
它遍历枚举的所有可能的整数值,并查看所提供动物的 'flag' 是否存在。如果是,它会添加到 return 数组。
假设枚举值不多,你可以试试:
private static void Main(string[] args)
{
var type = AnimalType.Wolf;
foreach (var x in GetAllPossibleCombinationWith(type))
{
Console.WriteLine(x);
}
Console.ReadLine();
}
public static IEnumerable<AnimalType> GetAllPossibleCombinationWith(AnimalType type) // Bird
{
var maxValue = Enum.GetValues(typeof(AnimalType)).Cast<int>().Max();
var combinationValue =2* maxValue - 1;
for (int i = 0; i < combinationValue; i++)
{
var val = (AnimalType) i;
if ((val & type) == type) yield return val;
}
}
[Flags]
public enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8,
Fish = 16
}
它假定标志值中没有 "hole"。