【问题标题】:C# - Creating a EnumRandomizer ClassC# - 创建一个 EnumRandomizer 类
【发布时间】:2011-08-03 19:59:04
【问题描述】:

我不知道如何正确地做到这一点。我找到了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 类覆盖了枚举 Sex;Weapon 类覆盖了枚举 WeaponType,等等.);

这也是低效的,因为它需要我编写代​​码,而这些代码必须为同一件事一遍又一遍地重新实现。因此,显而易见的解决方案是创建一个 Random 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)];
    }
}

有接受者吗?

【问题讨论】:

    标签: c# class random enums


    【解决方案1】:
    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 类,而不是您传入的类型。泛型是让您以尝试的方式动态分配类型的原因。这就是类型安全操作需要它们的原因。

    【讨论】:

    • 需要强制转换Enum.GetValues的返回值
    • 谢谢。你介意给我看一个如何实现这种行为的简单例子吗?我对泛型非常陌生,我不知道如何调用该方法。
    • @Holland 我会添加一个使用示例。
    【解决方案2】:

    制作泛型方法

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

    或者这是不推荐使用的正确版本的类,因为它会导致boxing/unboxing

        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));
    

    希望对你有帮助

    【讨论】:

    • 查看编辑后的帖子,你的类会导致枚举的装箱拆箱,这比泛型慢,泛型更清晰,不需要类型转换
    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多