열거 형에서 임의의 값을 어떻게 선택합니까?


170

C #에 임의의 열거가 주어지면 임의의 값을 어떻게 선택합니까?

(나는이 기본적인 질문을 찾지 못했습니다. 누구에게나 참조 할 수 있도록 잠시 후 내 답변을 게시 할 것이지만 자유롭게 자신의 답변을 게시하십시오.)

답변:


282
Array values = Enum.GetValues(typeof(Bar));
Random random = new Random();
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length));

40
random그래도 반복 루프를 반복 해서 작성하지 마십시오. 그렇지 않으면 동일한 값을 계속 얻게됩니다.
ChrisF

1
임의적이어야합니까? 다음 (값. 길이 -1)?
uriDium

7
@uriDium 아니요, 인수는 어떤 값이 가장 큰 값을 반환하는지 지정합니다 (예 : 최대 빼기 1 )
mafu

길이 -1
Bojidar Stanchev

DarinDimitrov IMO @ChrisF의 첫 번째 의견은 Chris에게 감사의 말을 전하는 메모입니다.
maytham-ɯɐɥʇʎɐɯ

60

Enum.GetValues를 사용하여 모든 값의 배열을 검색하십시오. 그런 다음 임의의 배열 항목을 선택하십시오.

static Random _R = new Random ();
static T RandomEnumValue<T> ()
{
    var v = Enum.GetValues (typeof (T));
    return (T) v.GetValue (_R.Next(v.Length));
}

테스트:

for (int i = 0; i < 10; i++) {
    var value = RandomEnumValue<System.DayOfWeek> ();
    Console.WriteLine (value.ToString ());
}

->

Tuesday
Saturday
Wednesday
Monday
Friday
Saturday
Saturday
Saturday
Friday
Wednesday

5

당신은 이것을 할 수 있습니다 :

var rnd = new Random();
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length);

어레이를 저장할 필요가 없습니다


GetNames배열을 반환합니다.
Nathan Tuggy 2016 년

당신이 그것을 저장할 필요가 없다는 것을 의미했습니다. 나의 나쁜
Breno Angelotti

누군가 루프에서이 작업을 수행하는 경우 배열에서 캐싱하는 대신 매번 GetNames를 호출합니다. 이렇게하면 코드가 느려져 귀하의 기여가 무엇인지 알 수 없습니까?
Bojidar Stanchev

@BojidarStanchev IF , 내 경우에는 훌륭하게 작동합니다, 감사합니다 Breno :)
Jaacko Torus

3

다음은 Extension Methodusing 과 같은 대체 버전 LINQ입니다.

using System;
using System.Linq;

public static class EnumExtensions
{
    public static Enum GetRandomEnumValue(this Type t)
    {
        return Enum.GetValues(t)          // get values from Type provided
            .OfType<Enum>()               // casts to Enum
            .OrderBy(e => Guid.NewGuid()) // mess with order of results
            .FirstOrDefault();            // take first item in result
    }
}

public static class Program
{
    public enum SomeEnum
    {
        One = 1,
        Two = 2,
        Three = 3,
        Four = 4
    }

    public static void Main()
    {
        for(int i=0; i < 10; i++)
        {
            Console.WriteLine(typeof(SomeEnum).GetRandomEnumValue());
        }
    }           
}

2
1
4
4
4
3
2
4
1
3


2

전화 Enum.GetValues; 이것은 열거 형에 가능한 모든 값을 나타내는 배열을 반환합니다. 이 배열에서 임의의 항목을 선택하십시오. 해당 항목을 원래 열거 형 유형으로 다시 캐스팅하십시오.


2

다음은 일반적인 기능입니다. RNG 생성을 고주파 코드 외부에 유지하십시오.

public static Random RNG = new Random();

public static T RandomEnum<T>()
{  
    Type type = typeof(T);
    Array values = Enum.GetValues(type);
    lock(RNG)
    {
        object value= values.GetValue(RNG.Next(values.Length));
        return (T)Convert.ChangeType(value, type);
    }
}

사용 예 :

System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>();

스레드 세이프가 아닌 정적 메소드를 갖는 것은 매우 위험합니다.
코드 InChaos

@CodesInChaos 당신이 맞아요. Random.Next ()는 스레드 안전하지 않으며 중단되면 0을 반환하기 시작합니다. 이 정보를 바탕으로 답변을 업데이트했습니다.
WHol

1

개인적으로 저는 확장 방법의 팬이므로 다음과 같은 것을 사용합니다 (실제 확장은 아니지만 비슷하게 보입니다).

public enum Options {
    Zero,
    One,
    Two,
    Three,
    Four,
    Five
}

public static class RandomEnum {
    private static Random _Random = new Random(Environment.TickCount);

    public static T Of<T>() {
        if (!typeof(T).IsEnum)
            throw new InvalidOperationException("Must use Enum type");

        Array enumValues = Enum.GetValues(typeof(T));
        return (T)enumValues.GetValue(_Random.Next(enumValues.Length));
    }
}

[TestClass]
public class RandomTests {
    [TestMethod]
    public void TestMethod1() {
        Options option;
        for (int i = 0; i < 10; ++i) {
            option = RandomEnum.Of<Options>();
            Console.WriteLine(option);
        }
    }

}

1
C # 7.3부터 일반 형식을 열거 형으로 제한 할 수 있습니다. public static T Of<T>() where T : Enum docs.microsoft.com/en-us/visualstudio/releasenotes/…
nitzel

0

랜덤 클래스 확장으로 적응 :

public static class RandomExtensions
{   
    public static T NextEnum<T>(this Random random)
    {
        var values = Enum.GetValues(typeof(T));
        return (T)values.GetValue(random.Next(values.Length));
    }
}

사용 예 :

var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();

0

임의의 값을 캐스트 할 수도 있습니다.

using System;

enum Test {
  Value1,
  Value2,
  Value3
}

class Program {
  public static void Main (string[] args) {
    var max = Enum.GetValues(typeof(Test)).Length;
    var value = (Test)new Random().Next(0, max - 1);
    Console.WriteLine(value);
  }
}

그러나이 라이브러리 의 것과 같은 더 나은 무작위 추출기 를 사용해야합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.