etc./StackOverFlow

어떻게 int를 열거형으로 캐스팅할 수 있습니까?

청렴결백한 만능 재주꾼 2021. 10. 9. 02:26
반응형

질문자 :lomaxx


C#에서 int enum 으로 캐스팅하는 방법은 무엇입니까?



정수에서 :

 YourEnum foo = (YourEnum)yourInt;

문자열에서:

 YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString); // The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(",")) { throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.") }

업데이트:

번호에서 당신은 또한 할 수 있습니다

 YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);

FlySwat

그냥 던지세요:

 MyEnum e = (MyEnum)3;

Enum.IsDefined를 사용하여 범위 내에 있는지 확인할 수 있습니다.

 if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }

Matt Hamilton

또는 한 줄짜리 대신 확장 방법을 사용하십시오.

 public static T ToEnum<T>(this string enumString) { return (T) Enum.Parse(typeof (T), enumString); }

용법:

 Color colorEnum = "Red".ToEnum<Color>();

또는

 string color = "Red"; var colorEnum = color.ToEnum<Color>();

Abdul Munim

완전한 대답을 얻으려면 사람들이 .NET에서 열거형이 내부적으로 어떻게 작동하는지 알아야 한다고 생각합니다.

물건이 작동하는 방식

.NET의 열거형은 값 집합(필드)을 기본 유형(기본값은 int )에 매핑하는 구조입니다. 그러나 실제로 열거형이 매핑되는 정수 유형을 선택할 수 있습니다.

 public enum Foo : short

이 경우 열거형은 short 데이터 유형에 매핑됩니다. 즉, 메모리에 short로 저장되고 캐스팅하고 사용할 때 short로 작동합니다.

IL 관점에서 보면 (normal, int) 열거형은 다음과 같습니다.

 .class public auto ansi serializable sealed BarFlag extends System.Enum { .custom instance void System.FlagsAttribute::.ctor() .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) } .field public static literal valuetype BarFlag AllFlags = int32(0x3fff) .field public static literal valuetype BarFlag Foo1 = int32(1) .field public static literal valuetype BarFlag Foo2 = int32(0x2000) // and so on for all flags or enum values .field public specialname rtspecialname int32 value__ }

여기서 주의해야 할 점은 value__ 가 열거형 값과 별도로 저장된다는 것입니다. 위 열거형 Foo value__ 의 유형은 int16입니다. 이것은 기본적으로 유형이 일치 하는 한 열거형에 원하는 것을 저장할 수 있음을 의미합니다.

System.Enum 이 값 유형이라는 점을 지적하고 싶습니다 BarFlag 가 메모리에서 4바이트 Foo 가 2를 차지한다는 것을 의미합니다. 예를 들어 기본 유형의 크기(실제로는 더 많은 그보다 복잡하지만 야...).

대답

따라서 열거형에 매핑하려는 정수가 있는 경우 런타임은 4바이트를 복사하고 다른 이름(열거형 이름)으로 지정하기만 하면 됩니다. 데이터가 값 유형으로 저장되기 때문에 복사는 암시적입니다. 즉, 기본적으로 비관리 코드를 사용하는 경우 데이터를 복사하지 않고 열거형과 정수를 교환할 수 있습니다.

안전하게 하려면 기본 유형이 동일하거나 암시적으로 변환 가능하다는 것을 알고 열거형 값이 존재하는지 확인하는 것이 가장 좋습니다(기본적으로 확인되지 않습니다!).

이것이 어떻게 작동하는지 보려면 다음 코드를 시도하십시오.

 public enum MyEnum : int { Foo = 1, Bar = 2, Mek = 5 } static void Main(string[] args) { var e1 = (MyEnum)5; var e2 = (MyEnum)6; Console.WriteLine("{0} {1}", e1, e2); Console.ReadLine(); }

e2 로의 캐스팅도 작동합니다! 위의 컴파일러 관점에서 이것은 의미가 있습니다. value__ 필드는 단순히 5 또는 6으로 채워지고 Console.WriteLineToString() e1 의 이름 e2 의 이름은 확인되지 않습니다.

의도한 것이 Enum.IsDefined(typeof(MyEnum), 6) 를 사용하여 캐스팅하는 값이 정의된 열거형에 매핑되는지 확인합니다.

또한 컴파일러가 실제로 이를 확인하더라도 열거형의 기본 유형에 대해 명시적입니다. 나는 길에서 어떤 놀라움도 만나지 않도록 하기 위해 이 일을 하고 있습니다. 이러한 놀라움을 실제로 보려면 다음 코드를 사용할 수 있습니다(실제로 저는 데이터베이스 코드에서 이런 일이 많이 일어나는 것을 보았습니다).

 public enum MyEnum : short { Mek = 5 } static void Main(string[] args) { var e1 = (MyEnum)32769; // will not compile, out of bounds for a short object o = 5; var e2 = (MyEnum)o; // will throw at runtime, because o is of type int Console.WriteLine("{0} {1}", e1, e2); Console.ReadLine(); }

atlaste

다음 예를 들어보세요.

 int one = 1; MyEnum e = (MyEnum)one;

abigblackman

이 코드를 사용하여 열거형으로 캐스팅하고 있습니다.

 if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast; else { //handle it here, if its not defined }

최고의 솔루션이라고 생각합니다.


MSkuta

아래는 Enums에 대한 멋진 유틸리티 클래스입니다.

 public static class EnumHelper { public static int[] ToIntArray<T>(T[] value) { int[] result = new int[value.Length]; for (int i = 0; i < value.Length; i++) result[i] = Convert.ToInt32(value[i]); return result; } public static T[] FromIntArray<T>(int[] value) { T[] result = new T[value.Length]; for (int i = 0; i < value.Length; i++) result[i] = (T)Enum.ToObject(typeof(T),value[i]); return result; } internal static T Parse<T>(string value, T defaultValue) { if (Enum.IsDefined(typeof(T), value)) return (T) Enum.Parse(typeof (T), value); int num; if(int.TryParse(value,out num)) { if (Enum.IsDefined(typeof(T), num)) return (T)Enum.ToObject(typeof(T), num); } return defaultValue; } }

Tawani

숫자 값의 경우 다음과 상관없이 객체를 반환하므로 더 안전합니다.

 public static class EnumEx { static public bool TryConvert<T>(int value, out T result) { result = default(T); bool success = Enum.IsDefined(typeof(T), value); if (success) { result = (T)Enum.ToObject(typeof(T), value); } return success; } }

Sébastien Duval

4.0 .NET Framework를 사용할 준비가 되었다면 매우 유용하고 [Flags] 특성과 잘 어울리는 새로운 Enum.TryParse() 함수가 있습니다. Enum.TryParse 메서드 참조 (문자열, TEnum%)


Ryan Russon

비트 마스크 역할을 하고 [Flags] 열거형에서 하나 이상의 값을 나타낼 수 있는 정수가 있는 경우 이 코드를 사용하여 개별 플래그 값을 목록으로 구문 분석할 수 있습니다.

 for (var flagIterator = 0; flagIterator < 32; flagIterator++) { // Determine the bit value (1,2,4,...,Int32.MinValue) int bitValue = 1 << flagIterator; // Check to see if the current flag exists in the bit mask if ((intValue & bitValue) != 0) { // If the current flag exists in the enumeration, then we can add that value to the list // if the enumeration has that flag defined if (Enum.IsDefined(typeof(MyEnum), bitValue)) Console.WriteLine((MyEnum)bitValue); } }

enum 형의 기본 유형이 부호 있는 32비트 정수라고 가정합니다. 다른 숫자 유형인 경우 해당 유형의 비트를 반영하도록 하드코딩된 32를 변경해야 합니다(또는 Enum.GetUnderlyingType() 사용하여 프로그래밍 방식으로 파생).


Evan M

MyEnum 유형에 대한 개체가 있습니다. 좋다

 var MyEnumType = typeof(MyEnum);

그 다음에:

 Enum.ToObject(typeof(MyEnum), 3)

L. D.

이것은 플래그 열거 인식 안전 변환 방법입니다.

 public static bool TryConvertToEnum<T>(this int instance, out T result) where T: Enum { var enumType = typeof (T); var success = Enum.IsDefined(enumType, instance); if (success) { result = (T)Enum.ToObject(enumType, instance); } else { result = default(T); } return success; }

Daniel Fisher lennybacon

여기에 이미지 설명 입력

문자열을 ENUM으로 변환하거나 int를 ENUM 상수로 변환하려면 Enum.Parse 함수를 사용해야 합니다. 다음은 youtube 비디오 https://www.youtube.com/watch?v=4nhx4VwdRDk 입니다. 실제로 문자열로 시연하고 int에도 동일하게 적용됩니다.

코드는 아래와 같이 진행됩니다. 여기서 "red"는 문자열이고 "MyColors"는 색상 상수가 있는 색상 ENUM입니다.

 MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");

Shivprasad Koirala

원래 질문에서 약간 벗어나 있지만 스택 오버플로 질문 Get int value from enum에 대한 답변이 유용하다는 것을 알았습니다. public const int 속성을 사용하여 정적 클래스를 생성하면 int 상수를 쉽게 수집할 수 있으며 사용할 때 int 할 필요가 없습니다.

 public static class Question { public static readonly int Role = 2; public static readonly int ProjectFunding = 3; public static readonly int TotalEmployee = 4; public static readonly int NumberOfServers = 5; public static readonly int TopBusinessConcern = 6; }

분명히 열거형 유형 기능 중 일부는 손실되지만 많은 데이터베이스 ID 상수를 저장하기 위해 꽤 깔끔한 솔루션처럼 보입니다.


Ted

다음은 약간 더 나은 확장 방법입니다.

 public static string ToEnumString<TEnum>(this int enumValue) { var enumString = enumValue.ToString(); if (Enum.IsDefined(typeof(TEnum), enumValue)) { enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString(); } return enumString; }

Kamran Shahid

이것은 Tawani의 유틸리티 클래스 와 같은 제네릭을 사용하여 .NET 4.0에서 부분적으로 일치하는 대상 열거형으로 정수 또는 문자열을 구문 분석합니다. 불완전할 수 있는 명령줄 스위치 변수를 변환하는 데 사용하고 있습니다. 열거형은 null일 수 없으므로 논리적으로 기본값을 제공해야 합니다. 다음과 같이 호출할 수 있습니다.

 var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);

코드는 다음과 같습니다.

 using System; public class EnumParser<T> where T : struct { public static T Parse(int toParse, T defaultVal) { return Parse(toParse + "", defaultVal); } public static T Parse(string toParse, T defaultVal) { T enumVal = defaultVal; if (defaultVal is Enum && !String.IsNullOrEmpty(toParse)) { int index; if (int.TryParse(toParse, out index)) { Enum.TryParse(index + "", out enumVal); } else { if (!Enum.TryParse<T>(toParse + "", true, out enumVal)) { MatchPartialName(toParse, ref enumVal); } } } return enumVal; } public static void MatchPartialName(string toParse, ref T enumVal) { foreach (string member in enumVal.GetType().GetEnumNames()) { if (member.ToLower().Contains(toParse.ToLower())) { if (Enum.TryParse<T>(member + "", out enumVal)) { break; } } } } }

참고: 질문은 정수에 관한 것이었습니다. 아무도 언급하지 않은 정수는 Enum.TryParse()에서도 명시적으로 변환하지 않을 것입니다.


CZahrobsky

문자열에서: (Enum.Parse가 만료되었습니다. Enum.TryParse 사용)

 enum Importance {} Importance importance; if (Enum.TryParse(value, out importance)) { }

Will Yu

좀 더 견고하게 하기 위해서는 이완과 일치하는 일부 유형을 구축해야 합니다.

 public static T ToEnum<T>(dynamic value) { if (value == null) { // default value of an enum is the object that corresponds to // the default value of its underlying type // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table value = Activator.CreateInstance(Enum.GetUnderlyingType(typeof(T))); } else if (value is string name) { return (T)Enum.Parse(typeof(T), name); } return (T)Enum.ToObject(typeof(T), Convert.ChangeType(value, Enum.GetUnderlyingType(typeof(T)))); }

테스트 케이스

 [Flags] public enum A : uint { None = 0, X = 1 < 0, Y = 1 < 1 } static void Main(string[] args) { var value = EnumHelper.ToEnum<A>(7m); var x = value.HasFlag(AX); // true var y = value.HasFlag(AY); // true var value2 = EnumHelper.ToEnum<A>("X"); var value3 = EnumHelper.ToEnum<A>(null); Console.ReadKey(); }

user11523568

Int32Enum 하는 확장 메서드입니다.

값이 가능한 최대값보다 높은 경우에도 비트 플래그를 준수합니다. 예를 들어 1 , 2 , 4의 가능성이 있는 열거형이 있지만 int가 9 인 경우 8이 없는 경우 1 로 이해합니다. 이를 통해 코드 업데이트보다 먼저 데이터 업데이트를 수행할 수 있습니다.

 public static TEnum ToEnum<TEnum>(this int val) where TEnum : struct, IComparable, IFormattable, IConvertible { if (!typeof(TEnum).IsEnum) { return default(TEnum); } if (Enum.IsDefined(typeof(TEnum), val)) {//if a straightforward single value, return that return (TEnum)Enum.ToObject(typeof(TEnum), val); } var candidates = Enum .GetValues(typeof(TEnum)) .Cast<int>() .ToList(); var isBitwise = candidates .Select((n, i) => { if (i < 2) return n == 0 || n == 1; return n / 2 == candidates[i - 1]; }) .All(y => y); var maxPossible = candidates.Sum(); if ( Enum.TryParse(val.ToString(), out TEnum asEnum) && (val <= maxPossible || !isBitwise) ){//if it can be parsed as a bitwise enum with multiple flags, //or is not bitwise, return the result of TryParse return asEnum; } //If the value is higher than all possible combinations, //remove the high imaginary values not accounted for in the enum var excess = Enumerable .Range(0, 32) .Select(n => (int)Math.Pow(2, n)) .Where(n => n <= val && n > 0 && !candidates.Contains(n)) .Sum(); return Enum.TryParse((val - excess).ToString(), out asEnum) ? asEnum : default(TEnum); }

Chad Hedgcock

제 경우에는 WCF 서비스에서 열거형을 반환해야 했습니다. enum.ToString()뿐만 아니라 친숙한 이름도 필요했습니다.

여기 내 WCF 클래스가 있습니다.

 [DataContract] public class EnumMember { [DataMember] public string Description { get; set; } [DataMember] public int Value { get; set; } public static List<EnumMember> ConvertToList<T>() { Type type = typeof(T); if (!type.IsEnum) { throw new ArgumentException("T must be of type enumeration."); } var members = new List<EnumMember>(); foreach (string item in System.Enum.GetNames(type)) { var enumType = System.Enum.Parse(type, item); members.Add( new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) }); } return members; } }

다음은 Enum에서 설명을 가져오는 Extension 메서드입니다.

 public static string GetDescriptionValue<T>(this T source) { FieldInfo fileInfo = source.GetType().GetField(source.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) { return attributes[0].Description; } else { return source.ToString(); } }

구현:

 return EnumMember.ConvertToList<YourType>();

LawMan

입력 데이터를 사용자가 원하는 열거형 으로 변환하는 데 도움이 될 수 있습니다. 기본적으로 int 인 아래와 같은 열거 형이 있다고 가정합니다. 열거형의 처음에 기본값을 추가하십시오. 입력 값과 일치하는 항목이 없을 때 도우미 medthod에서 사용됩니다.

 public enum FriendType { Default, Audio, Video, Image } public static class EnumHelper<T> { public static T ConvertToEnum(dynamic value) { var result = default(T); var tempType = 0; //see Note below if (value != null && int.TryParse(value.ToString(), out tempType) && Enum.IsDefined(typeof(T), tempType)) { result = (T)Enum.ToObject(typeof(T), tempType); } return result; } }

NB: 여기서 enum은 기본적으로 int 이기 때문에 값을 int로 구문 분석하려고 합니다. 이와 같이 enum을 정의하면 바이트 유형입니다.

 public enum MediaType : byte { Default, Audio, Video, Image }

도우미 메서드에서 구문 분석을 다음에서 변경해야 합니다.

 int.TryParse(value.ToString(), out tempType)

에게

byte.TryParse(value.ToString(), out tempType)

다음 입력에 대한 방법을 확인합니다.

 EnumHelper<FriendType>.ConvertToEnum(null); EnumHelper<FriendType>.ConvertToEnum(""); EnumHelper<FriendType>.ConvertToEnum("-1"); EnumHelper<FriendType>.ConvertToEnum("6"); EnumHelper<FriendType>.ConvertToEnum(""); EnumHelper<FriendType>.ConvertToEnum("2"); EnumHelper<FriendType>.ConvertToEnum(-1); EnumHelper<FriendType>.ConvertToEnum(0); EnumHelper<FriendType>.ConvertToEnum(1); EnumHelper<FriendType>.ConvertToEnum(9);

내 영어 미안


reza.cse08

C#에서 int를 enum으로 캐스팅하는 쉽고 명확한 방법:

 public class Program { public enum Color : int { Blue = 0, Black = 1, Green = 2, Gray = 3, Yellow = 4 } public static void Main(string[] args) { // From string Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green")); // From int Console.WriteLine((Color)2); // From number you can also Console.WriteLine((Color)Enum.ToObject(typeof(Color), 2)); } }

Mohammad Aziz Nabizada

Enum 으로 및 Enum에서 캐스트하는 다양한 방법

 enum orientation : byte { north = 1, south = 2, east = 3, west = 4 } class Program { static void Main(string[] args) { orientation myDirection = orientation.north; Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north Console.WriteLine((byte)myDirection); //output 1 string strDir = Convert.ToString(myDirection); Console.WriteLine(strDir); //output north string myString = “north”; //to convert string to Enum myDirection = (orientation)Enum.Parse(typeof(orientation),myString); } }

gmail user

이 열거형 확장의 일부를 어디서 얻었는지 더 이상 모르지만 stackoverflow에서 가져온 것입니다. 죄송합니다! 그러나 나는 이것을 가져 와서 플래그가있는 열거 형으로 수정했습니다. 플래그가 있는 열거형의 경우 다음을 수행했습니다.

 public static class Enum<T> where T : struct { private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>(); private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k)); public static T? CastOrNull(int value) { T foundValue; if (Values.TryGetValue(value, out foundValue)) { return foundValue; } // For enums with Flags-Attribut. try { bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0; if (isFlag) { int existingIntValue = 0; foreach (T t in Enum.GetValues(typeof(T))) { if ((value & Convert.ToInt32(t)) > 0) { existingIntValue |= Convert.ToInt32(t); } } if (existingIntValue == 0) { return null; } return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true)); } } catch (Exception) { return null; } return null; } }

예시:

 [Flags] public enum PetType { None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32 }; integer values 1=Dog; 13= Dog | Fish | Bird; 96= Other; 128= Null;

Franki1986

명시적 변환 Cast int to enum 또는 enum to int를 사용하기만 하면 됩니다.

 class Program { static void Main(string[] args) { Console.WriteLine((int)Number.three); //Output=3 Console.WriteLine((Number)3);// Outout three Console.Read(); } public enum Number { Zero = 0, One = 1, Two = 2, three = 3 } }

Shivam Mishra

using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; namespace SamplePrograme { public class Program { public enum Suit : int { Spades = 0, Hearts = 1, Clubs = 2, Diamonds = 3 } public static void Main(string[] args) { //from string Console.WriteLine((Suit) Enum.Parse(typeof(Suit), "Clubs")); //from int Console.WriteLine((Suit)1); //From number you can also Console.WriteLine((Suit)Enum.ToObject(typeof(Suit) ,1)); } } }

Aswal

아래와 같이 하면 됩니다.

 int intToCast = 1; TargetEnum f = (TargetEnum) intToCast ;

올바른 값만 캐스팅하고 그렇지 않으면 예외를 throw할 수 있는지 확인하려면:

 int intToCast = 1; if (Enum.IsDefined(typeof(TargetEnum), intToCast )) { TargetEnum target = (TargetEnum)intToCast ; } else { // Throw your exception. }

IsDefined를 사용하는 것은 비용이 많이 들고 단순히 캐스팅하는 것 이상이므로 사용 여부를 결정하는 구현에 따라 다릅니다.


Mselmi Ali

간단하게 int를 열거형으로 캐스팅할 수 있습니다.

 public enum DaysOfWeeks { Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7, } var day= (DaysOfWeeks)5; Console.WriteLine("Day is : {0}", day); Console.ReadLine();

Inam Abbas

확장 방법을 사용할 수 있습니다.

 public static class Extensions { public static T ToEnum<T>(this string data) where T : struct { if (!Enum.TryParse(data, true, out T enumVariable)) { if (Enum.IsDefined(typeof(T), enumVariable)) { return enumVariable; } } return default; } public static T ToEnum<T>(this int data) where T : struct { return (T)Enum.ToObject(typeof(T), data); } }

아래 코드와 같이 사용하십시오.

열거형:

 public enum DaysOfWeeks { Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7, }

용법:

 string Monday = "Mon"; int Wednesday = 3; var Mon = Monday.ToEnum<DaysOfWeeks>(); var Wed = Wednesday.ToEnum<DaysOfWeeks>();

Reza Jenabi

두 가지 지침이 필요합니다.

 YourEnum possibleEnum = (YourEnum)value; // There isn't any guarantee that it is part of the enum if (Enum.IsDefined(typeof(YourEnum), possibleEnum)) { // Value exists in YourEnum }

Cesar Alvarado Diaz

출처 : http:www.stackoverflow.com/questions/29482/how-can-i-cast-int-to-enum

반응형