sub - C#에서 열거 형을 어떻게 열거합니까?
t enum c# (18)
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
나는 이것이 아주 천천히 느리다는 모호한 소문을 들었다. 누구 알아? - 오리온 에드워즈, 2003 년 10 월 15 일 1:31 7
배열을 캐싱하면 속도가 상당히 빨라질 것이라고 생각합니다. 매번 리플렉션을 통해 새로운 배열을 얻는 것 같습니다. 차라리:
Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums)
{
DoSomething(suitEnum);
}
적어도 조금 더 빨랐어 요?
C #에서 열거 형을 어떻게 열거 할 수 있습니까?
예를 들어 다음 코드는 컴파일되지 않습니다.
public enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
public void EnumerateAllSuitsDemoMethod()
{
foreach (Suit suit in Suit)
{
DoSomething(suit);
}
}
그리고 다음과 같은 컴파일 타임 오류가 발생합니다.
'Suit'는 '유형'이지만 '변수'처럼 사용됩니다.
두 번째 키워드 인 Suit
키워드에서는 실패합니다.
저는 이것이 더 낫다는 의견이나 다른 좋은 해결책을 말하는 좋은 의견을 갖고 있지 않습니다.
enum 값이 0에서 n - 1까지의 범위를 가지면 일반적인 대안 :
public void EnumerateEnum<T>()
{
int length = Enum.GetValues(typeof(T)).Length;
for (var i = 0; i < length; i++)
{
var @enum = (T)(object)i;
}
}
열거 형 값이 인접하고 열거 형의 첫 번째 요소와 마지막 요소를 제공 할 수있는 경우 다음을 수행하십시오.
public void EnumerateEnum()
{
for (var i = Suit.Spade; i <= Suit.Diamond; i++)
{
var @enum = i;
}
}
하지만 이것은 반복적으로 열거 된 것이 아닙니다. 두 번째 방법은 다른 어떤 방법보다 훨씬 빠릅니다 ...
ToString ()을 사용하여 깃발 배열을 분할하고 구문 분석합니다.
[Flags]
public enum ABC {
a = 1,
b = 2,
c = 4
};
public IEnumerable<ABC> Getselected (ABC flags)
{
var values = flags.ToString().Split(',');
var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
return enums;
}
ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
Console.WriteLine(item.ToString() + " ID=" + (int)item);
}
값보다 각 열거 형의 이름을 실제로 인쇄하고 싶은 것처럼 보입니다. Enum.GetNames()
가 올바른 접근 방법 인 것 같습니다.
public enum Suits
{
Spades,
Hearts,
Clubs,
Diamonds,
NumSuits
}
public void PrintAllSuits()
{
foreach (string name in Enum.GetNames(typeof(Suits)))
{
System.Console.WriteLine(name);
}
}
그런데 값을 증가시키는 것은 열거 형의 값을 열거하는 좋은 방법이 아닙니다. 대신이 작업을 수행해야합니다.
대신 Enum.GetValues(typeof(Suit))
사용합니다.
public enum Suits
{
Spades,
Hearts,
Clubs,
Diamonds,
NumSuits
}
public void PrintAllSuits()
{
foreach (var suit in Enum.GetValues(typeof(Suits)))
{
System.Console.WriteLine(suit.ToString());
}
}
나는 그것이 조금 지저분한 것을 알고있다. 그러나 만일 당신이 one-liners의 팬이라면, 여기는 하나 다.
((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
네가 사용할 수 있다고 생각해.
Enum.GetNames(Suit)
도대체 내가 두 개의 펜스를 던져 버릴거야. 가장 간단한 확장자
public static class EnumExtensions
{
/// <summary>
/// Gets all items for an enum value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns></returns>
public static IEnumerable<T> GetAllItems<T>(this Enum value)
{
return (T[])Enum.GetValues(typeof (T));
}
}
간단하고 @ Jeppe-Stig-Nielsen 님의 덧글을 빨리 정리하십시오.
또한 리플렉션을 사용하여 열거 형의 public 정적 멤버에 직접 바인딩 할 수 있습니다.
typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
.ToList().ForEach(x => DoSomething(x.Name));
빌드 및 런타임에 속도와 형식 검사가 필요한 경우이 도우미 메서드는 LINQ를 사용하여 각 요소를 캐스팅하는 것보다 낫습니다.
public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
if (typeof(T).BaseType != typeof(Enum))
{
throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
}
return Enum.GetValues(typeof(T)) as T[];
}
그리고 아래와 같이 사용할 수 있습니다 :
static readonly YourEnum[] _values = GetEnumValues<YourEnum>();
물론 IEnumerable<T>
반환 할 수는 있지만 여기서는 아무것도 사지 않습니다.
세 가지 방법 :
1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere
GetEnumValues
가 type 인스턴스에 도입 된 이유는 무엇인지 잘 모릅니다. 전혀 읽을 수 없습니다.
Enum<T>
형 ( Enum<T>
)과 같은 도우미 클래스를 갖는 것이 가장 읽기 쉽고 기억하기 쉬운 클래스입니다.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
public static IEnumerable<T> GetValues()
{
return (T[])Enum.GetValues(typeof(T));
}
public static IEnumerable<string> GetNames()
{
return Enum.GetNames(typeof(T));
}
}
이제 전화주세요 :
Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style
퍼포먼스가 중요하다면 캐싱을 사용할 수도 있지만, 이것이 전혀 문제가되지는 않을 것이라고 생각합니다.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
//lazily loaded
static T[] values;
static string[] names;
public static IEnumerable<T> GetValues()
{
return values ?? (values = (T[])Enum.GetValues(typeof(T)));
}
public static IEnumerable<string> GetNames()
{
return names ?? (names = Enum.GetNames(typeof(T)));
}
}
열거 형을 상호 작용할 수있는 것으로 변환하는 간단하고 일반적인 방법 :
public static Dictionary<int, string> ToList<T>() where T : struct
{
return ((IEnumerable<T>)Enum
.GetValues(typeof(T)))
.ToDictionary(
item => Convert.ToInt32(item),
item => item.ToString());
}
그리고:
var enums = EnumHelper.ToList<MyEnum>();
유형이 enum
형이 될 것이라는 것을 알고 있지만 컴파일 타임에 정확한 유형이 무엇인지 알 수 없다면 어떻게 될까요?
public class EnumHelper
{
public static IEnumerable<T> GetValues<T>()
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
public static IEnumerable getListOfEnum(Type type)
{
MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
return (IEnumerable)getValuesMethod.Invoke(null, null);
}
}
getListOfEnum
메소드는 리플렉션을 사용해 모든 enum 형을 취해, 모든 enum 치의 IEnumerable
를 돌려줍니다.
용법:
Type myType = someEnumValue.GetType();
IEnumerable resultEnumerable = getListOfEnum(myType);
foreach (var item in resultEnumerable)
{
Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}
일부 .NET Framework 버전은 Enum.GetValues
지원하지 않습니다. Ideas 2.0 의 좋은 해결 방법은 다음과 같습니다 . Compact Framework의 Enum.GetValues :
public List<Enum> GetValues(Enum enumeration)
{
List<Enum> enumerations = new List<Enum>();
foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
BindingFlags.Static | BindingFlags.Public))
{
enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
}
return enumerations;
}
reflection 을 포함하는 모든 코드와 마찬가지로, 한 번만 실행되고 결과가 캐시되도록 조치를 취해야합니다.
컴팩트 프레임 워크 (3.5)에서 작동 하고 컴파일 타임에 유형 검사 를 지원하는 내 솔루션을 추가하기 만하면됩니다.
public static List<T> GetEnumValues<T>() where T : new() {
T valueType = new T();
return typeof(T).GetFields()
.Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
.Distinct()
.ToList();
}
public static List<String> GetEnumNames<T>() {
return typeof (T).GetFields()
.Select(info => info.Name)
.Distinct()
.ToList();
}
- 누군가 T valueType = new T()
제거하는 방법을 알고 있다면, 해결책을 T valueType = new T()
기쁩니다.
호출은 다음과 같습니다.
List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
Enum
을 반복하는 두 가지 방법이 있습니다.
1. var values = Enum.GetValues(typeof(myenum))
2. var values = Enum.GetNames(typeof(myenum))
첫 번째는 object
의 배열에서 값을 폼에 제공하고 두 번째는 String
배열로 값을 제공합니다.
foreach
루프에서 다음과 같이 사용하십시오.
foreach(var value in values)
{
//Do operations here
}
enum
유형은 값을 "열거"하는 컨테이너가 아니라 해당 유형의 변수에 대해 가능한 값을 열거 하여 정의되기 때문에 "열거 유형"이라고합니다.
실제로 enum 유형은 "기본"정수 유형으로 간주되므로 각 enum 값은 정수 값에 해당합니다 (일반적으로 암시 적이지만 수동으로 지정할 수 있음). C #을 설계했습니다. 어떤 식 으로든 그 형식의 정수를 "명명 된"값이 아니더라도 enum 변수에 채울 수 있습니다.
이름에서 알 수 있듯이 System.Enum.GetNames 메서드 를 사용하여 열거 형 값의 이름 인 문자열 배열을 검색 할 수 있습니다.
편집 : 대신 System.Enum.GetValues 메서드를 제안해야합니다. 죄송합니다.
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}
(현재 받아 들여지는 대답은 내가 틀릴 수도 있지만 내가 필요하다고 생각하지 않는 캐스트를 가지고있다.)
public void PrintAllSuits()
{
foreach(string suit in Enum.GetNames(typeof(Suits)))
{
Console.WriteLine(suit);
}
}