Dapatkan nilai int dari enum dalam C #

1825

Saya memiliki kelas yang disebut Questions(jamak). Di kelas ini ada enum yang disebut Question(tunggal) yang terlihat seperti ini.

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

Di Questionskelas saya memiliki get(int foo)fungsi yang mengembalikan Questionsobjek untuk itu foo. Apakah ada cara mudah untuk mendapatkan nilai integer dari enum sehingga saya bisa melakukan sesuatu seperti ini Questions.Get(Question.Role)?

Jim
sumber
31
Untuk sebaliknya: cast-int-to-enum-in-c-sharp .
nawfal
11
Saya tahu saya terlambat ke pesta, tetapi alih-alih mendefinisikan metode get(int foo)Anda karena Anda dapat mendefinisikannya get(Question foo)saat melakukan casting di dalam metode, Anda dapat memanggil metode Anda sebagaiQuestions.Get(Question.Role)
Joe

Jawaban:

2354

Cukup masukkan enum, mis

int something = (int) Question.Role;

Hal di atas akan berfungsi untuk sebagian besar enum yang Anda lihat di alam liar, seperti tipe yang mendasari standar untuk enum int.

Namun, seperti yang ditunjukkan cecilphillip , enum dapat memiliki tipe yang berbeda. Jika enum dinyatakan sebagai uint, long, atau ulong, harus dilemparkan dengan jenis enum; misalnya untuk

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

kamu harus menggunakan

long something = (long)StarsInMilkyWay.Wolf424B;
Tetraneutron
sumber
23
@Harry itu tidak benar. Anda dapat membuat Enumerasi tanpa casting, itu tidak diperlukan. dan saya hanya menetapkan nomor dalam kasus khusus, sebagian besar waktu, saya membiarkannya sebagai nilai default. tetapi Anda dapat melakukan enum Test { Item = 1 }dan melihat bahwa 1 == (int)Test.Itemitu sama.
Jaider
33
@Jaider (int)Test.ItemItu pemain! () adalah operator pemeran eksplisit.
Sinthia V
48
@Sinthia V katanya Anda bisa membuatnya tanpa casting, yang benar
Paul Ridgway
7
Jika tipe yang mendasari untuk enum Questiontidak inttetapi para longpemain ini akan memotong Rolenilai integral s!
quaylar
1
Saat Anda menerima Enumsebagai parameter, Anda tahu hanya sejumlah tetap nilai integral yang bisa Anda dapatkan. Di sisi lain, jika Anda hanya mengambil int, maka Anda harus memvalidasi jika itu intdalam nilai yang diterima., Sehingga menyulitkan kode. Anda selalu dapat mengganti tanda tangan Anda seperti `` `public void MyMethod (int x) {// melakukan sesuatu dengan x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
percebus
307

Sejak Enum dapat menjadi semua jenis terpisahkan ( byte, int, short, dll), cara yang lebih kuat untuk mendapatkan nilai integral yang mendasari enum akan memanfaatkan GetTypeCodemetode dalam hubungannya dengan Convertkelas:

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

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

Ini harus bekerja terlepas dari tipe integral yang mendasarinya.

cecilphillip
sumber
32
Teknik ini membuktikan nilainya bagi saya ketika berhadapan dengan tipe generik di mana T: enum (sebenarnya T: struct, IConvertible tapi itu cerita yang berbeda).
aboy021
1
Bagaimana Anda akan memodifikasi ini untuk mencetak nilai sisi heksadesimal? Contoh ini menunjukkan nilai desimal. Masalahnya adalah vartipe object, jadi Anda perlu membuka kotaknya dan itu menjadi berantakan daripada yang saya inginkan.
Mark Lakata
2
Saya pikir Anda harus mengubah contoh untuk object val = Convert...etcpara vardalam contoh Anda akan selalu object.
Mesh
2
@TimAbell Yang saya benar-benar dapat katakan adalah bahwa kami menemukan bahwa halaman aspx yang dikompilasi secara dinamis (di mana Anda harus menggunakan file .cs ke server langsung) menetapkan integer secara berbeda untuk setiap nilai. Itu berarti bahwa objek serial satu mesin, deserialising dengan nilai yang berbeda pada mesin yang berbeda dan secara efektif menjadi rusak (menyebabkan jam kebingungan). Kami mengangkatnya dengan MS dan saya ingat mereka mengatakan bahwa bilangan bulat autogenerasi tidak dijamin sama ketika dibangun di berbagai versi kerangka kerja.
NickG
4
@TimAbell Pada kesempatan terpisah, pengembang menghapus nilai Enum yang usang / tidak terpakai menyebabkan semua nilai lainnya dalam urutan dikeluarkan oleh satu. Dengan demikian, standar pengkodean kami sekarang mensyaratkan bahwa ID selalu ditentukan secara eksplisit, jika tidak menambahkan / menghapus atau bahkan memformat otomatis kode (misalnya mengurutkan berdasarkan abjad) akan mengubah semua nilai yang menyebabkan korupsi data. Saya akan sangat menyarankan siapa pun untuk menentukan semua bilangan bulat Enum secara eksplisit. Ini sangat penting jika berkorelasi dengan nilai yang disimpan secara eksternal (database).
NickG
199

Deklarasikan sebagai kelas statis yang memiliki konstanta publik:

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

Dan kemudian Anda dapat referensi sebagai Question.Role, dan selalu mengevaluasi ke intatau apa pun yang Anda definisikan sebagai.

PablosBicicleta
sumber
31
Saya akan menggunakan static readonly intkarena konstanta dikompilasi ke dalam nilai kerasnya. Lihat stackoverflow.com/a/755693/492
CAD cowok
96
Solusi ini sebenarnya tidak memberikan manfaat nyata dari enum yang sangat diketik. Jika saya hanya ingin melewatkan GameState-enum-parameter ke metode tertentu misalnya, kompiler seharusnya tidak mengizinkan saya untuk melewatkan variabel int sebagai parameter.
thgc
12
@CADBloke itulah tepatnya yang akan Anda gunakan constdan bukan static readonlykarena setiap kali Anda membandingkan static readonlyAnda membuat panggilan metode untuk mendapatkan nilai variabel sedangkan dengan constAnda membandingkan dua tipe nilai secara langsung.
blockloop
3
@ brettof86 Ya, const akan lebih cepat, jika batasan kompilasi tidak akan menjadi masalah maka itu semua baik.
CAD cowok
2
@ Zack Saya tidak menjelaskannya dengan sangat baik, compilation limitationmaksud saya bahwa nilainya adalah hard-coded ketika Anda mengkompilasinya sehingga setiap perubahan pada nilai tersebut akan mengharuskan semua majelis yang menggunakannya perlu dikompilasi ulang. Saya cenderung setuju dengan Anda tentang penggunaan karena mengubah nilai akan memiliki implikasi yang luas.
CAD cowok
87
Question question = Question.Role;
int value = (int) question;

Akan menghasilkan value == 2.

jerigen
sumber
34
Pertanyaan variabel temporer tidak perlu.
Gishu
1
Jadi sesuatu seperti Pertanyaan ini. Dapatkan (Convert.ToInt16 (Question.Applications))
jim
6
Anda bisa melemparkan ke arah mana pun; satu-satunya untuk menonton adalah bahwa enum tidak menegakkan apa-apa (nilai enum bisa 288, meskipun tidak ada Pertanyaan ada dengan nomor itu)
Marc Gravell
@jim: Tidak, cukup masukkan nilainya: Pertanyaan. Dapatkan (int) Pertanyaan. Aplikasi);
Guffa
1
@ Gishu Bisa dibilang ... dipertanyakan. ;)
Felix D.
79

Pada catatan terkait, jika Anda ingin mendapatkan intnilai dari System.Enum, maka diberikan di esini:

Enum e = Question.Role;

Kamu bisa menggunakan:

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

Dua yang terakhir benar-benar jelek. Saya lebih suka yang pertama.

nawfal
sumber
1
Yang kedua adalah yang tercepat.
Johan B
1
Sebagai seseorang yang terbiasa menggunakan modding Mixins in Minecraft, yang kedua sepertinya adalah pemenang yang jelas.
Sollace
40

Ini lebih mudah daripada yang Anda pikirkan - enum sudah merupakan int. Itu hanya perlu diingatkan:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
Michael Petrotta
sumber
15
Nitpick: ini enum sudah int. Enum lain mungkin tipe yang berbeda - coba "enum SmallEnum: byte {A, B, C}"
mqp
9
Sepenuhnya benar. Referensi C #: "Setiap tipe enumerasi memiliki tipe yang mendasarinya, yang dapat berupa tipe integral kecuali karakter."
Michael Petrotta
33

Contoh:

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

Dan dalam kode di belakang untuk mendapatkan nilai enum:

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

atau

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

Enum akan bertambah 1, dan Anda dapat mengatur nilai awal. Jika Anda tidak menetapkan nilai awal, nilai awalnya akan ditetapkan sebagai 0.

Peter Mortensen
sumber
6
Apakah ini benar-benar kompilasi?
Peter Mortensen
Bisakah sesuatu yang Raj juga menjadi Rahul atau Priyanka? Nilai-nilai Anda bertentangan dan harus digandakan menjadi unik misalnya 0, 1, 2, 4, 8, dll. Ini adalah masalah utama saya dengan enum.
Timothy Gonzalez
@TimothyGonzalez sebenarnya enum cukup hitung 1 jika Anda tidak secara eksplisit menentukan nilainya;)
derHugo
@ DerHugo itu tergantung jika Anda menganggap nilai numerik menjadi basis 10 atau basis 2.
Timothy Gonzalez
@TimothyGonzalez baik tidak ada banyak untuk menganggap ... Aku hanya menunjukkan bahwa secara default mereka hanya menghitung 1di intkecuali Anda secara eksplisit menentukan sebaliknya
derHugo
28

Saya baru-baru ini dikonversi dari menggunakan enum dalam kode saya yang mendukung daripada menggunakan kelas dengan konstruktor yang dilindungi dan instance statis yang telah ditentukan (terima kasih kepada Roelof - C # Pastikan Nilai Valum Enum yang Valid - Metode Futureproof ).

Sehubungan dengan itu, berikut ini bagaimana saya sekarang mendekati masalah ini (termasuk konversi implisit ke / dari 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)
}

Keuntungan dari pendekatan ini adalah Anda mendapatkan semua yang Anda miliki dari enum, tetapi kode Anda sekarang jauh lebih fleksibel, jadi jika Anda perlu melakukan tindakan yang berbeda berdasarkan nilai Question, Anda dapat memasukkan logika ke dalam Questiondirinya sendiri (yaitu dalam OO yang disukai mode) sebagai kebalikan dari menempatkan banyak pernyataan kasus di seluruh kode Anda untuk menangani setiap skenario.


NB: Jawaban diperbarui 2018-04-27 untuk memanfaatkan fitur C # 6; yaitu ekspresi pernyataan dan definisi tubuh ekspresi lambda. Lihat riwayat revisi untuk kode asli. Ini memiliki manfaat membuat definisi sedikit kurang bertele-tele; yang telah menjadi salah satu keluhan utama tentang pendekatan jawaban ini.

JohnLBevan
sumber
2
Saya kira itu adalah trade off antara pemeran eksplisit dan kode yang harus Anda tulis untuk mengelak. Tetap mencintai implementasinya hanya berharap itu tidak terlalu panjang. +1
Lankymart
3
Saya telah menggunakan beberapa jenis kelas yang terstruktur mirip dengan ini. Saya menemukan mereka bekerja keajaiban ketika mencoba mengikuti metodologi "jangan biarkan aku menjadi idiot nanti".
James Haug
20

Jika Anda ingin mendapatkan bilangan bulat untuk nilai enum yang disimpan dalam variabel, untuk jenis yang akan digunakan Question, untuk digunakan misalnya dalam suatu metode, Anda bisa melakukan ini yang saya tulis dalam contoh ini:

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

Ini akan mengubah judul jendela menjadi 4, karena variabelnya Geselecteerdadalah Talen.Nederlands. Jika saya mengubahnya Talen.Portugeesdan memanggil metode itu lagi, teks akan berubah menjadi 3.

Mathijs Van Der Slagt
sumber
3
coding dalam bahasa belanda. Oh sayang.
WiseStrawberry
Sayangnya, pendekatan ini memberikan kinerja yang buruk semakin banyak Anda menggunakannya. Saya mencobanya di beberapa kode saya, dan seiring berjalannya waktu, aplikasi saya semakin lama semakin lambat, dengan semakin sedikit penggunaan CPU. Ini menyiratkan bahwa utas sedang menunggu sesuatu - Saya mengasumsikan semacam pengumpulan sampah, mungkin karena tinju parameter enum ke ToInt32 (). Dengan beralih ke int.Parse () sederhana, saya dapat menghilangkan kinerja buruk ini sepenuhnya, dan kinerja tetap sama tidak peduli berapa lama kode berjalan.
Greg
16

Untuk memastikan nilai enum ada dan kemudian menguraikannya, Anda juga dapat melakukan hal berikut.

// 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() + ".");
Nathon
sumber
14

Mungkin saya melewatkannya, tetapi adakah yang mencoba metode ekstensi generik sederhana?

Ini sangat bagus untuk saya. Anda dapat menghindari tipe cast di API Anda dengan cara ini tetapi pada akhirnya itu menghasilkan operasi tipe perubahan. Ini adalah kasus yang bagus untuk pemrograman Roslyn agar kompiler membuat metode GetValue <T> untuk Anda.

    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;
    }
}
Doug
sumber
Mungkin karena melakukan (int) customFlag kurang mengetik di sekitar dan melakukan hal yang kurang lebih sama?
Tim Keating
Re "Mungkin aku rindu itu, tapi telah ada yang mencoba generik sederhana metode ekstensi ?" : SixOThree mengatakan "Gunakan metode ekstensi sebagai gantinya" dan Bronek mengatakan "Anda dapat melakukan ini dengan menerapkan metode ekstensi ke tipe enum yang Anda tentukan" .
Peter Mortensen
13

Satu lagi cara untuk melakukannya:

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

Ini akan menghasilkan:

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

... adalah deklarasi yang bagus.

Anda harus memberikan hasilnya ke int seperti:

int Question = (int)QuestionType.Role

Kalau tidak, jenisnya tetap QuestionType.

Tingkat keketatan ini adalah cara C #.

Salah satu alternatif adalah dengan menggunakan deklarasi kelas sebagai gantinya:

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
}

Tidak terlalu elegan untuk dideklarasikan, tetapi Anda tidak perlu memasukkannya dalam kode:

int Question = QuestionType.Role

Atau, Anda mungkin merasa lebih nyaman dengan Visual Basic, yang melayani harapan seperti ini di banyak bidang.

WonderWorker
sumber
11
int number = Question.Role.GetHashCode();

numberharus memiliki nilai 2.

JaimeArmenta
sumber
GetHashCode adalah salah satu cara untuk mendapatkan nilai dari topeng umum Enum
ThanhLD
Catatan bahwa ini hanya "legit" untuk bool*, byte, ushort, int, dan uint**. GetHashCode untuk tipe lain memodifikasi nilainya, misalnya melakukan beberapa bitshifts dan xors. (* 1/0, ** dicetak ke int tentu saja). Tapi secara keseluruhan, jangan lakukan ini kecuali jika itu kode pribadi Anda.
AnorZaken
10

Anda dapat melakukan ini dengan menerapkan metode ekstensi ke tipe enum yang Anda tentukan:

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

Ini menyederhanakan mendapatkan nilai int dari nilai enum saat ini:

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

atau

int value = Question.Role.getNumberValue();
Bronek
sumber
5
Bronek, apa yang Anda lakukan adalah membuat sintaks tidak informatif melalui metode ekstensi (non generic btw) yang sebenarnya membutuhkan waktu lebih lama untuk menulis. Saya gagal melihat bagaimana itu lebih baik daripada solusi asli oleh Tetraneutron. Jangan biarkan ini menjadi obrolan, bantuan selalu diterima di stackoverflow dan semua orang di sini ada untuk membantu. Silakan berikan komentar saya sebagai kritik yang membangun.
Benjamin Gruenbaum
2
Benjamin, pertama-tama, mengapa Anda menghapus komentar saya? Saya tidak mengerti keputusan Anda - mungkin orang lain di komunitas akan setuju dengan komentar saya. Kedua, solusi saya membungkus Tetraneutron dan secara akurat lebih mudah dan kurang menulis karena metode ekstensi disarankan oleh IntelliSense. Jadi saya pikir keputusan Anda tidak memihak dan representatif. Saya melihat banyak jawaban serupa di Stack dan itu OK. Lagi pula saya menggunakan solusi saya dan mungkin ada beberapa orang akan memilih solusi saya di masa depan, tetapi titik-titik negatif ini membuat lebih sulit untuk menemukan. Kebanyakan dari semuanya itu benar dan tidak menyalin.
Bronek
3
@Bronek Jika Anda tidak ping saya, saya tidak mendapatkan indikasi bahwa Anda menjawab. Saya tidak menghapus komentar Anda. Saya tidak memiliki kemampuan atau ingin melakukannya. Kemungkinan seorang mod datang dan menghapusnya - Anda dipersilakan memberi tanda untuk perhatian moderator dan bertanya mengapa atau lebih baik lagi - bertanya di Meta Stack Overflow . Saya punya pendapat tentang solusi Anda dari sudut pandang pemrograman yang benar-benar ada di tangan saya - ini adalah komentar untuk memulai, tidak perlu menganggapnya sebagai masalah pribadi.
Benjamin Gruenbaum
8

Gunakan metode ekstensi sebagai gantinya:

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

Dan penggunaannya sedikit lebih cantik:

var intValue = Question.Role.IntValue();
SixOThree
sumber
7
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 a 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);
}
Gauravsa
sumber
suit - "10. (permainan kartu) Masing-masing set kartu yang dibedakan berdasarkan warna dan / atau lambang tertentu, seperti sekop, hati, berlian atau klub kartu tradisional Anglo, Hispanik dan Perancis yang dimainkan."
Peter Mortensen
Penjelasan kode sampel akan dilakukan secara berurutan (dengan mengedit jawaban Anda , bukan di sini dalam komentar).
Peter Mortensen
nol umumnya dicadangkan untuk keadaan tidak disetel / tidak dikenal dalam enum, tidak biasa untuk mendefinisikannya seperti itu
Chad Grant
6

Menggunakan:

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

Itu akan menghasilkan value == 2.

Ini hanya benar jika enum cocok di dalam sebuah int.

GinCanhViet
sumber
1
Ini hanya benar jika enum cocok di dalam sebuah inttentu saja, karena GetHashCodemengembalikan bilangan bulat.
RB.
5

Karena enum dapat dideklarasikan dengan beberapa tipe primitif, metode ekstensi umum untuk menggunakan tipe enum apa pun dapat berguna.

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;
Jeffrey Ferreiras
sumber
4

Berikut ini adalah metode ekstensi

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
sumber
4

Retasan favorit saya dengan enum int atau lebih kecil:

GetHashCode();

Untuk enum

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

Ini,

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

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

output

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Penolakan:

Itu tidak bekerja untuk enum berdasarkan panjang.

Erik Karlsson
sumber
3

Solusi termudah yang dapat saya pikirkan adalah membebani Get(int)metode seperti ini:

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

di mana [modifiers]umumnya dapat sama dengan Get(int)metode. Jika Anda tidak dapat mengedit Questionskelas atau karena beberapa alasan tidak mau, Anda dapat membebani metode ini dengan menulis ekstensi:

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

Contoh yang ingin saya sarankan "untuk mendapatkan nilai 'int' dari enum", adalah

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

int answer = (int)Sample.Book;

Sekarang jawabannya adalah 1.

Vivek
sumber
3

Menggunakan:

Question question = Question.Role;
int value = Convert.ToInt32(question);
Peter Mortensen
sumber
2

Coba yang ini alih-alih konversi enum ke int:

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

Dalam Visual Basic, seharusnya:

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

Private value As Integer = CInt(Question.Role)
VPP
sumber
3
Pertanyaannya adalah untuk C #.
Ctrl S
2
Judulnya "Dapatkan nilai int dari enum dalam C #" .
Peter Mortensen
0

Saya datang dengan metode ekstensi ini yang mencakup fitur bahasa saat ini. Dengan menggunakan dinamis, saya tidak perlu menjadikan ini metode generik dan menentukan jenis yang membuat doa tetap lebih sederhana dan konsisten:

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;
    }
Jeff
sumber
tolong tidak, Anda bisa melakukan semua ini dalam satu baris Convert.Changetype (e, e.GetTypeCode ()) dan dapatkan objek kembali, tidak perlu dinamika atau metode ekstensi
Chad Grant
Saya tidak setuju menggunakan Convert. Hanya menggunakan gips akan lebih mudah. Maksud saya adalah untuk dapat mengkonversi enum apa pun ke nilainya tanpa menggunakan gips. Hal ini memungkinkan perubahan tipe enum tanpa harus mengubah semua gips terkait - tetapi kapan ini terjadi ?. Metode ekstensi berfungsi dengan benar. Namun, saya mengalami masalah dengan itu, karena dinamis, kompilator tidak dapat mengetik cek (untuk seluruh pernyataan tampaknya) yang berarti pemeriksaan tipe terjadi ketika dijalankan - bukan solusi yang baik. Saya pikir saya akan kembali ke gips.
Jeff
1
Saya tidak mengatakan menggunakannya di atas pemeran, hanya saja kode ini tidak masuk akal dan tidak menghasilkan apa-apa, sebenarnya membuat masalahnya menjadi lebih buruk. Saya akan merekomendasikan menghapus solusi ini
Chad Grant