Saya memiliki kelas yang disebut Pertanyaan
(jamak). Di kelas ini ada enum disebut Pertanyaan
(tunggal) yang terlihat seperti ini.
public enum Question
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
Di Pertanyaan
kelas, aku punya get(int foo)
fungsi yang mengembalikan sebuah Pertanyaan
benda itu foo
. Apakah ada cara mudah untuk mendapatkan nilai integer dari enum sehingga saya bisa melakukan sesuatu seperti Pertanyaan.Mendapatkan(Pertanyaan.Peran)
?
Hanya melemparkan enum, misalnya
int something = (int) Question.Role;
Di atas akan bekerja untuk sebagian besar dari enums anda lihat di alam liar, seperti default yang mendasari tipe enum adalah int
.
Namun, sebagai cecilphillip poin, enums dapat memiliki mendasari yang berbeda jenis.
Jika enum dinyatakan sebagai uint
, lama
, atau ulong
, itu harus dilemparkan ke tipe enum; misalnya untuk
enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};
anda harus menggunakan
long something = (long)StarsInMilkyWay.Wolf424B;
Sejak Enums dapat berupa tipe integral (byte
, int
, pendek
, dll.), cara yang lebih kuat untuk mendapatkan yang mendasari nilai integral dari enum akan membuat penggunaan GetTypeCode
metode dalam hubungannya dengan Convert
kelas:
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 yang mendasari tipe integral.
Mendeklarasikan sebagai statis kelas memiliki semua konstanta:
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 itu sebagai Pertanyaan.Peran
, dan selalu mengevaluasi ke sebuah int
atau apa pun yang anda tentukan sebagai.
Pada catatan terkait, jika anda ingin mendapatkan int
nilai dari Sistem.Enum
, kemudian diberikan e
di sini:
Enum e = Question.Role;
Anda dapat 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 terakhir yang polos jelek. Saya lebih suka yang pertama.
It's mudah daripada yang anda pikirkan - enum sudah int. Hanya saja perlu diingatkan:
int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
Contoh:
public Enum EmpNo
{
Raj = 1,
Rahul,
Priyanka
}
Dan dalam kode balik 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
Enums akan kenaikan sebesar 1, dan anda dapat mengatur nilai awal. Jika anda don't mengatur nilai awal ini akan ditugaskan sebagai 0 pada awalnya.
Saya baru-baru ini telah dikonversi jauh dari menggunakan enums dalam kode saya mendukung bukan menggunakan kelas dengan dilindungi konstruktor dan yang telah ditetapkan statis contoh (terima kasih untuk Roelof - https://stackoverflow.com/questions/10704863/c-sharp-ensure-valid-enum-values-futureproof-method).
Dalam cahaya itu, di bawah ini's bagaimana saya'd 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 segala sesuatu yang anda akan memiliki dari enum, tapi anda kode's sekarang jauh lebih fleksibel, jadi jika anda perlu untuk melakukan tindakan yang berbeda berdasarkan nilai Pertanyaan
, anda dapat menempatkan logika menjadi Pertanyaan
itu sendiri (yaitu di pilihan OO fashion) sebagai lawan untuk menempatkan banyak laporan kasus sepanjang kode anda untuk mengatasi masing-masing skenario.
NB: Jawaban diperbarui 2018-04-27 untuk menggunakan C# 6 fitur; yaitu deklarasi ekspresi dan ekspresi lambda tubuh definisi. Lihat update sejarah untuk kode asli. Ini memiliki keuntungan dari pembuatan definisi yang sedikit kurang verbose; yang telah menjadi salah satu keluhan utama tentang jawaban ini's pendekatan.
Jika anda ingin mendapatkan sebuah integer untuk enum nilai yang disimpan dalam variabel, yang jenis akan menjadi Pertanyaan
, untuk digunakan sebagai contoh dalam metode ini, anda hanya dapat melakukan ini saya menulis 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 untuk 4 karena variabel Geselecteerd
adalah Talen.Nederlands
. Jika saya mengubah itu untuk Talen.Portugees
dan memanggil metode lagi, teks akan berubah menjadi 3.
Aku punya waktu yang sulit menemukan solusi sederhana ini di internet dan saya tidak't menemukan itu, jadi saya sedang menguji sesuatu dan menemukan ini. Semoga ini bisa membantu. ;)
Untuk memastikan enum nilai yang ada dan kemudian mengurai itu, 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() + ".");
Saya harap ini membantu.
Mungkin aku kehilangan itu tetapi telah ada yang mencoba sederhana generik metode penyuluhan. Ini karya besar untuk saya. Anda dapat menghindari jenis dilemparkan dalam API anda dengan cara ini tetapi pada akhirnya mengakibatkan perubahan jenis operasi. Ini adalah kasus yang baik untuk pemrograman Roselyn untuk memiliki compiler membuat 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;
}
}
public enum QuestionType
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
...adalah deklarasi.
Anda harus melemparkan hasil untuk int seperti:
int Question = (int)QuestionType.Role
Jika tidak, jenis ini masih QuestionType
.
Tingkat keketatan adalah C# dengan cara.
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
}
It's kurang elegan untuk menyatakan, tapi anda don't perlu untuk cor dalam kode:
int Question = QuestionType.Role
Atau, anda mungkin merasa lebih nyaman dengan Visual Basic, yang melayani untuk jenis harapan di banyak daerah.
Anda dapat melakukan ini dengan menerapkan Metode Penyuluhan untuk anda yang didefinisikan tipe enum:
public static class MyExtensions
{
public static int getNumberValue(this Question questionThis)
{
return (int)questionThis;
}
}
Ini menyederhanakan mendapatkan int nilai saat ini enum nilai:
Question question = Question.Role;
int value = question.getNumberValue();
atau
int value = Question.Role.getNumberValue();
Bagaimana metode penyuluhan sebagai gantinya:
public static class ExtensionMethods
{
public static int IntValue(this Enum argEnum)
{
return Convert.ToInt32(argEnum);
}
}
Dan penggunaan sedikit lebih cantik:
var intValue = Question.Role.IntValue();
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);
}
Sejak enums dapat dinyatakan dengan beberapa tipe primitif, generik metode penyuluhan untuk melemparkan setiap tipe enum 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;
Berikut adalah metode penyuluhan
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;
}
My fav hack dengan int atau lebih kecil enums:
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
Disclaimer: Doesn't bekerja untuk enums berdasarkan panjang