web-dev-qa-db-ja.com

C#のenumからint値を取得する

私はQuestions(複数形)というクラスを持っています。このクラスにはQuestion(単数形)と呼ばれるenumがあります。

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

Questionsクラスには、そのQuestionsfooオブジェクトを返すget(int foo)関数があります。私はQuestions.Get(Question.Role)のようなことができるように列挙型から整数値を取得する簡単な方法はありますか?

1576
jim

列挙型をキャストするだけです。

int something = (int) Question.Role;

Enumのデフォルトの基本型はintなので、上で挙げたものはあなたが実際に見ているほとんどのenumに対して有効です。

しかし、 cecilphillip が指摘しているように、enumは異なる基本型を持つことができます。 enumがuintlong、またはulongとして宣言されている場合は、enumの型にキャストする必要があります。例えばにとって

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

あなたが使うべきです

long something = (long)StarsInMilkyWay.Wolf424B;
2044
Tetraneutron

Enumは任意の整数型(byteintshortなど)である可能性があるので、enumの基礎となる整数値を取得するためのより堅牢な方法は、GetTypeCodeクラスと一緒にConvertメソッドを使用することです。

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

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

基礎となる整数型に関係なく、これは機能するはずです。

273
cecilphillip

パブリック定数を持つ静的クラスとして宣言します。

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またはあなたがそれを定義するものは何でも評価します。

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

value == 2になります。

77
jerryjvl

関連するメモとして、System.Enumからintの値を取得したい場合は、ここでeを指定します。

Enum e = Question.Role;

あなたが使用することができます:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

最後の2つは明らかに醜いです。私は最初のものが好きです。

62
nawfal

想像以上に簡単です - 列挙型はすでにint型です。注意する必要があります。

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

例:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

そして、enum値を取得するための背後のコードでは、

int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1

または

int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2

Enumは1ずつ増加し、開始値を設定できます。開始値を設定しないと、最初は0に割り当てられます。

26
sooraj

私は最近、保護されたコンストラクターと事前定義された静的インスタンスを持つクラスを代わりに使用して、コードで列挙型を使用することから転換しました(Roelof- C#Ensure 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形式)は、コード全体に大量のcaseステートメントを配置して各シナリオに対処するのとは対照的です。


NB:C#6の機能を利用するために2018-04-27に更新された回答。すなわち、宣言式とラムダ式の本体定義。元のコードについては、 改訂履歴 を参照してください。これには、定義を少し冗長にするという利点があります。これは、この回答のアプローチに関する主な不満の1つでした。

23
JohnLBevan

たとえばメソッドで使用するために、変数に格納されているenum値の整数を取得したい場合は、その型をQuestionにします。

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

変数GeselecteerdTalen.Nederlandsであるため、これはウィンドウタイトルを4に変更します。それをTalen.Portugeesに変更してメソッドをもう一度呼び出すと、テキストは3に変わります。

私はインターネット上でこの単純な解決策を見つけるのに苦労し、それを見つけることができなかったので、私は何かをテストしていてこれを見つけました。お役に立てれば。 ;)

17

Enum値が存在することを確認してからそれを解析するには、次のこともできます。

// Fake Day of Week
string strDOWFake = "SuperDay";
// Real Day of Week
string strDOWReal = "Friday";
// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
// This will never be reached since "SuperDay" 
// doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

これが役に立つことを願っています。

14
Nathon

たぶん私はそれを逃したが誰もが簡単な一般的な拡張方法を試したことがあります。これは私にとって素晴らしい仕事です。この方法で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;
    }
}    
11
Doug

もう1つの方法があります:

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

結果は次のようになります。

Name: Role, Value: 2
11
plavozont
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

...は良い宣言です。

次のように結果をintにキャストする必要があります。

int Question = (int)QuestionType.Role

それ以外の場合、型はまだQuestionTypeです。

このレベルの厳密さはC#のやり方です。

代わりにクラス宣言を使用することもできます。

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

宣言するのはそれほどエレガントではありませんが、コードでキャストする必要はありません。

int Question = QuestionType.Role

あるいは、多くの分野でこの種の期待に応えるVisual Basicを使用すると、より快適に感じるかもしれません。

10
int number = Question.Role.GetHashCode();

numberは値2を持つべきです。

9
JaimeArmenta

あなたは Extension Method をあなたの定義された列挙型に実装することによってこれを行うことができます:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

これにより、現在のenum値のint値を簡単に取得できます。

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

または

int value = Question.Role.getNumberValue();
8
Bronek

代わりに拡張メソッドはどうでしょうか。

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

そして使い方は少しきれいです:

var intValue = Question.Role.IntValue();
7
SixOThree
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);
}
4
Gauravsa

以下は拡張方法です

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;
}
3
Kamran Shahid

私のお気に入りはint以下のenumでハックする:

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    

免責事項: /に基づいて列挙型には機能しません

3
Erik Karlsson

「enumから「int」値を取得するには」という例を提案します。

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

int answer = (int)Sample.Book;

今答えは1になります。

これが誰かに役立つかもしれないと思います。

2
Vivek

列挙型は複数のプリミティブ型で宣言できるため、任意の列挙型をキャストするための一般的な拡張方法が役立ちます。

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

Enumをintに変換する代わりにこれを試してください。

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
1

私が考えることができる最も簡単な解決策はこのようにGet(int)メソッドをオーバーロードすることです:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

[modifiers]は一般的にGet(int)メソッドと同じにすることができます。 Questionsクラスを編集できない場合や何らかの理由で望まない場合は、拡張機能を記述してメソッドをオーバーロードできます。

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}
1
Grx70

VBでは。そのはず

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

Private value As Integer = CInt(Question.Role)
1
VPP
Question question = Question.Role;
int value = question.GetHashCode();

value == 2になります。

これは、enumがintに収まる場合にのみ当てはまります。

0
GinCanhViet

私は少しゲームに遅れましたが、私は現在の言語機能を含むこの拡張方法を思いつきました。動的を使用することで、これを一般的なメソッドにして、呼び出しをより単純で一貫性のあるものにする型を指定する必要はありません。何か問題があった場合はお知らせください。

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
        case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }
        case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }
        case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }
        case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }
        case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }
        case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }
        case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }
        case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }
0
Jeff