C # - Создание класса EnumRandomizer - PullRequest
3 голосов
/ 03 августа 2011

Я в тупик о том, как сделать это правильно. Я нашел this и не уверен, может ли это быть дубликатом.

Я начну с самого начала. Я смог реализовать предложение, данное в теме, которую я разместил, создав класс специально для рандомизации этого перечисления, которое выглядело следующим образом:

public class Foo
{
    public static Random rand = new Random();
    public static FooEnum[] values;
    public static FooEnum GetRandomFoo()
    {
       values = (FooEnum[]) Enum.GetValues(typeof(FooEnum));
       return values[rand.Next(0, Values.Length)];      
    }

    public enum FooEnum { A, B, C}
}

Это сработало довольно хорошо. Единственная проблема заключалась в том, что это, очевидно, привело к тому, что я обернул класс над своим перечислением, и поэтому всегда требовал от меня двух разных способов сказать одно и то же (например, класс Gender переносит enum Sex; класс Weapon переносит enum WeaponType и т.д. .);

Это также было неэффективно, потому что это потребовало бы от меня написания кода, который должен был бы переопределяться снова и снова для одной и той же вещи. Поэтому очевидным решением этого является создание класса Random Enum, который может принимать любой тип enum и рандомизировать его, используя следующий метод.

У кого-нибудь есть идеи, как это сделать? Мой метод не совсем работает:

public class EnumRandomizer 
    {

    private Random rand;
    private Type[] values;
    private int randomizerId;

    private static int randomizerCount = 0;

    public EnumRandomizer ()
    {
        rand = new Random();
        randomizerId = randomizerCount;
        randomizerCount++;

    }

    public Type RandomEnum(Type type)
    {
        values = (Type[]) Enum.GetValues(type);

        return values[rand.Next(0, values.Length)];
    }
}

Кто-нибудь принимает?

Ответы [ 2 ]

4 голосов
/ 04 августа 2011
public class EnumRandomizer
{
    public static Random rand = new Random();

    public static T GetRandomValue<T>()
    {
        T[] values = (T[])(Enum.GetValues(typeof(T)));
        return values[rand.Next(0, values.Length)];
    }
}

Использование:

public class Main
{
    public enum FooEnum { A, B, C }

    public static void Main(string[] args)
    {
        // Note that since the method does not take an argument which
        // specifies the generic type, you must provide it explicitly.
        FooEnum randomFoo = EnumRandomizer.GetRandomValue<FooEnum>();
    }
}

Что касается того, почему ваш оригинал не работает: то, что на самом деле разрешается, это класс System.Type, а не тип, который вы передаете. Обобщения - это то, что позволяет динамически назначать тип в манере вы пытаетесь Вот почему они необходимы для безопасной работы.

2 голосов
/ 04 августа 2011

Сделать общий метод

public static T GetRandomFoo<T>()
{
    Random rand = new Random();
    T[] values = (T[])Enum.GetValues(typeof(T));
    return values[rand.Next(0, values.Count)];
}

Или это правильная версия вашего класса, которую не рекомендуется использовать, поскольку она вызывает бокс / распаковку

    public class EnumRandomizer
    {

        private Random rand;
        private IList values;
        private int randomizerId;

        private static int randomizerCount = 0;

        public EnumRandomizer()
        {
            rand = new Random();
            randomizerId = randomizerCount;
            randomizerCount++;

        }

        public object RandomEnum(Type type)
        {
            values = Enum.GetValues(type);
            return values[rand.Next(0, values.Count)];
        }
    }

Вы можете использовать это так

   FooEnum f = (FooEnum)new EnumRandomizer().RandomEnum(typeof(FooEnum));

Надеюсь, это поможет

...