Случайное значение от перечисления Флагов

Скажите, что у меня есть функция, которая принимает перечисление, украшенное атрибутом Флагов. Если значение перечисления является комбинацией больше чем одного из перечислимых элементов, как я могу извлечь один из тех элементов наугад? У меня есть следующее, но кажется, что должен быть лучший путь.

[Flags]
enum Colours
{
    Blue = 1,
    Red = 2,
    Green = 4
}

public static void Main()
{
    var options = Colours.Blue | Colours.Red | Colours.Green;
    var opts = options.ToString().Split(',');
    var rand = new Random();
    var selected = opts[rand.Next(opts.Length)].Trim();
    var myEnum = Enum.Parse(typeof(Colours), selected);
    Console.WriteLine(myEnum);
    Console.ReadLine();
}
5
задан Chris Porter 8 June 2010 в 21:54
поделиться

4 ответа

var options = Colours.Blue | Colours.Green;

var matching = Enum.GetValues(typeof(Colours))
                   .Cast<Colours>()
                   .Where(c => (options & c) == c)    // or use HasFlag in .NET4
                   .ToArray();

var myEnum = matching[new Random().Next(matching.Length)];
9
ответ дан 18 December 2019 в 07:28
поделиться

Если вы не возражаете против небольшого приведения типов и ваше перечисление имеет базовый тип int, следующее будет работать и быстро.

var rand = new Random();
const int mask = (int)(Colours.Blue | Colours.Red | Colours.Green);
return (Colours)(mask & (rand.Next(mask) + 1));

Если вы хотите установить только один флаг, вы можете сделать следующее:

var rand = new Random();
return (Colours)(0x1 << (rand.Next(3)));
2
ответ дан 18 December 2019 в 07:28
поделиться

Вы можете вызвать Enum.GetValues ​​ , чтобы получить массив значений, определенных перечислением, например:

var rand = new Random();

Colors[] allValues = (Colors[])Enum.GetValues(typeof(Colors));
Colors value = allValues[rand.Next(allValues.Length)];
9
ответ дан 18 December 2019 в 07:28
поделиться

Если я правильно понял, вопрос касается возврата случайного значения перечисления из значения перечисления flags, а не возврата случайного члена из перечисления flags.

    [Flags]
    private enum Shot
    {
        Whisky = 1,
        Absynthe = 2,
        Pochin = 4,
        BrainEraser = Whisky | Absynthe | Pochin
    }

    [Test]
    public void Test()
    {
        Shot myCocktail = Shot.Absynthe | Shot.Whisky;

        Shot randomShotInCocktail = GetRandomShotFromCocktail(myCocktail);
    }

    private static Shot GetRandomShotFromCocktail(Shot cocktail)
    {
        Random random = new Random();

        Shot[] cocktailShots = Enum.GetValues(typeof(Shot)).
           Cast<Shot>().
           Where(x => cocktail.HasFlag(x)).ToArray();

        Shot randomShot = cocktailShots[random.Next(0, cocktailShots.Length)];

        return randomShot;
    }

Edit

И, очевидно, вы должны проверить, что перечисление является допустимым значением, например:

 Shot myCocktail = (Shot)666;

Edit

Simplified

1
ответ дан 18 December 2019 в 07:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: