2011-08-03 13 views
3

これを正しく行う方法については、私は困惑しています。 thisが見つかりました。これが重複している可能性があるかどうかはわかりません。C# - EnumRandomizerクラスの作成

私は最初からやります。

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} 
} 

これは非常によく働いていた:私は、私は次のように見えたという列挙型を、ランダム化のために特別にクラスを作成することにより、投稿のスレッドで与えられた提案を実装することができました。唯一の問題は、明らかに私の列挙型の上にクラスをラップしてしまったため、同じことを言うために2つの異なる方法が必要でした(クラスGenderはenum Sexをラップします;クラスWeaponはEnum WeaponTypeなどをラップします)。

これは、同じことについて何度も何度も再実装しなければならないコードを書く必要があるため、非効率的でした。したがって、これに対する明らかな解決策は、任意の種類の列挙型を取り、以下の方法を使用してランダム化するランダムな列挙型クラスを作成することです。

誰もがこれを行う方法上の任意のアイデアを持っていますか?私の方法はあまり働いていません。

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

すべてのテイク?

答えて

4
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

Enum.GetValuesの戻り値をキャストする必要があります。 – heisenberg

+0

ありがとうございます。このような動作を実装する方法の簡単な例を私に見せてもらえますか?私はジェネリックスにはまったく新しく、そのメソッドをどのように呼び出すべきかわかりません。 – zeboidlund

+0

@kekekelaいいキャッチです。更新されます。 – jdmichal

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)); 
のようにそれを使用することができ、使用することをお勧めしませんあなたのクラスの正しいバージョンであることを確認してください

希望します。

+0

なぜジェネリックを作るのですか?それはどうしたらうまくいくのですか? – zeboidlund

+0

編集された記事を参照してください、あなたのクラスは、一般的なよりも遅い、より一般的な型の変換を必要としないenumsのボクシングunboxingを引き起こします –

関連する問題