형변환 - C#에서 enum에서 int 값 가져 오기




t enum c# (17)

Questions (복수형)이라는 수업이 있습니다. 이 클래스에는 이와 같은 Question (단수)이라는 열거 형이 있습니다.

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Questions 클래스에는 해당 foo 대한 Questions 객체를 반환하는 get(int foo) 함수가 있습니다. Questions.Get(Question.Role) 과 같은 것을 할 수 있도록 enum에서 정수 값을 얻는 쉬운 방법이 있습니까?


Enums는 정수형 ( byte , int , short 등)이 될 수 있으므로 열거 형의 기본 정수 값을 얻는보다 강력한 방법은 Convert 클래스와 함께 GetTypeCode 메서드를 사용하는 것입니다.

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

이는 기초가되는 적분 유형에 관계없이 작동해야합니다.


enum에서 'int'값을 얻으려는 예제는 '

public enum Sample
{Book =1, Pen=2, Pencil =3}

int answer = (int)Sample.Book;

이제 대답은 1이 될 것입니다.

나는 이것이 누군가를 도울 수 있기를 바란다.


int 또는 더 작은 열거 형을 가진 내 fav 해킹 :

GetHashCode();

열거 형

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

var values = Enum.GetValues(typeof(Test));

foreach (var val in values) 
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

산출물

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

면책 조항 : 긴 기준의 enum에는 작동하지 않습니다 .


public 상수를 가진 정적 클래스로 선언하십시오.

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

그리고 당신은 Question.Role 그것을 참조 할 수 있습니다. 그리고 그것은 항상 int 또는 당신이 그것을 무엇으로 정의하든간에 평가됩니다.


그것을 할 수있는 또 하나의 방법 :

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

결과는 다음과 같습니다.

Name: Role, Value: 2

나는 최근에 대신 코드에서 열거 형을 사용하여 보호 된 생성자 및 미리 정의 된 정적 인스턴스 (Roelof - C # Valid Enum Values ​​- Futureproof Method 덕택)를 사용하여 클래스를 사용하도록 전환했습니다 .

그 점을 감안할 때, 다음은이 문제에 어떻게 접근했는지 ( int 에서 /로 암시 적 변환 포함)입니다.

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

이 접근법의 장점은 열거 형에서 얻은 모든 것을 얻을 수 있지만 코드가 훨씬 유연 해 지므로 Question 의 값에 따라 다른 작업을 수행해야 할 경우 로직을 Question 자체에 넣을 수 있습니다 (예 : 선호하는 OO 방식)을 사용하는 것이 좋습니다.

NB : C # 6 기능을 사용하기 위해 2018-04-27 업데이트되었습니다. 즉 선언 표현식과 람다 표현식 몸체 정의. 원본 코드의 업데이트 내역 보기 이것은 정의를 좀 덜 장황하게 만드는 장점이 있습니다. 이 답변에 대한 주요 불만 중 하나였습니다.


다음은 확장 메소드입니다.

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

대신 확장 방법은 어떻습니까?

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

사용법이 약간 더 예리합니다.

var intValue = Question.Role.IntValue();

생각보다 쉽습니다. enum은 이미 int입니다. 상기시켜 줄 필요가 있습니다.

int y = (int)Question.Role;
Console.WriteLine(y); // prints 2

어쩌면 나는 그것을 놓쳤지 만 누구나 간단한 일반적인 확장 방법을 시도했다. 이것은 나를 위해 위대한 작품. 이런 방식으로 API에서 타입 캐스트를 피할 수 있지만 궁극적으로는 타입 변경 작업이 발생합니다. Roselyn이 컴파일러에서 GetValue 메소드를 작성하도록 프로그래밍하는 좋은 사례입니다.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        //Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}    

열거 형은 여러 프리미티브 유형으로 선언 될 수 있기 때문에 모든 열거 형을 형변환하는 일반 확장 메소드가 유용 할 수 있습니다.

        enum Box
        {
            HEIGHT,
            WIDTH,
            DEPTH
        }

        public static void UseEnum()
        {
            int height = Box.HEIGHT.GetEnumValue<int>();
            int width = Box.WIDTH.GetEnumValue<int>();
            int depth = Box.DEPTH.GetEnumValue<int>();
        }

        public static T GetEnumValue<T>(this object e) => (T)e;

열거 형을 캐스팅하십시오.

int something = (int) Question.Role;

enum의 기본 기본 유형이 int 이므로 위의 내용은 야생에서 볼 수있는 대부분의 enum에서 작동합니다.

그러나 cecilphillip 지적 하듯이 enum은 다른 기본 유형을 가질 수 있습니다. 열거 형이 uint , long 또는 ulong 으로 선언되면 enum 형식으로 캐스팅해야합니다. 예를 들어

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

너는 사용해야한다.

long something = (long)StarsInMilkyWay.Wolf424B;

이 시도 :

int value = YourEnum.ToString("D");

있음. 그것은해야한다

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)

Question question = Question.Role;
int value = (int) question;

value == 2 됩니다.


int number = Question.Role.GetHashCode();

number2 의 값을 가져야합니다.


public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(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));

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}




int