c# nama enum untuk difilter dalam DropDownList alih-alih nilai

Saya memiliki daftar enum yang menyertakan enumerasi yang disebut Default.

public enum Fruits { Default = Banana, 
                    Banana = 1, 
                    Orange = 2, 
                    Grapefruit = 3 }

Saya perlu mengisi daftar dropdown yang mengecualikan bidang Default.

Html.DropDownList("fruitSelector", 
                Enum.GetValues(typeof(Fruits)).Cast<Fruits>()
                    .OrderBy(o => o.GetDescription())
                    .Where(o => o != Fruits.Default)
                    .Select(o => new SelectListItem() {Text = o.GetDescription(), Value = ((int) o).ToString()}), "-- All Fruits --",
                new {@class = "form-control", @aria_describedby="sizing-addon1"})

ketika saya mencoba memfilter pada Buah-buahan.Default itu menghapus KEDUA default dan Pisang. Bagaimana saya bisa melakukan perbandingan filter di mana saya hanya menghapus Default?

[[KOREKSI]] enum ini menduplikasi masalah saya. Sejujurnya saya tidak mengerti perbedaannya.

public enum Fruits
    {
        Default = Peaches,
        Peaches = 1,
        Bananas = 2,
        Grapefruit = 3,
        Apple = 101,
        Watermellon = 102
    }

or

public enum Fruits2
{
    Default = Mangos,
    Mangos = 1,
    Dates = 2,
    Figs = 3,
    Apples = 101,
    Limes = 102,
    Grapes = 103
}

person user1161137    schedule 15.08.2017    source sumber
comment
Apakah kode di atas dapat dikompilasi? Atau apakah Anda memiliki metode ekstensi yang tidak ditampilkan di sini? Kalau tidak, bagaimana o.GetDescription() dapat dikompilasi tanpa kesalahan?   -  person Sach    schedule 16.08.2017
comment
stackoverflow.com/questions/30467519/   -  person Dan Orlovsky    schedule 16.08.2017
comment
@Sach ya itu adalah metode untuk mendapatkan anotasi Deskripsi khusus. Anda dapat mengecualikannya.   -  person user1161137    schedule 16.08.2017


Jawaban (2)


Menurut saya apa yang Anda coba lakukan tidak mungkin sebagaimana adanya. Masalahnya adalah struktur Enum Anda.

public enum Fruits
{
    Default = Peaches,
    Peaches = 1,
    Bananas = 2,
    Grapefruit = 3,
    Apple = 101,
    Watermellon = 102
}

Anda mengatakan nilai Default adalah Peaches yang kemudian nilainya adalah 1. Yang intinya sama dengan (B adalah Peaches dan A adalah Default:

int B = 1;
int A = B;

Jadi ketika kita menggunakan Enum.Parse(), keduanya diperlakukan sama, dan mengambil nilai pertama. Anda akan mengerti ketika Anda melihat skenario berikut. Jalankan kode berikut, dengan Enum Anda saat ini:

var deflt = Enum.Parse(typeof(Fruits), Fruits.Default.ToString());
var peach = Enum.Parse(typeof(Fruits), Fruits.Peaches.ToString());
Console.WriteLine(deflt);
Console.WriteLine(peach);

Outputnya akan menjadi:

Bawaan

Bawaan

Kemudian ubah Enum Anda menjadi ini:

public enum Fruits
{
    Peaches = Default ,
    Default = 1,
    Bananas = 2,
    Grapefruit = 3,
    Apple = 101,
    Watermellon = 102
}

Dan jalankan kembali dua baris kode di atas. Output Anda kali ini adalah:

Persik

Persik

Artinya, Parse() mengambil Enum yang pertama kali ditentukan ketika ada persamaan seperti yang Anda miliki.

EDIT:

Penjelasan di atas sedikit salah, seperti yang ditunjukkan pada komentar di bawah oleh George Alexandria. Silakan lihat penjelasannya: Anda mendapatkan output yang berbeda saat menggunakan Peaches = Default , Default = 1, dan Default = Peaches, Peaches = 1, karena Anda memanggil Enum.ToString di Console.WriteLine. Jika Anda melihat var deflt, var peach Anda akan melihat bahwa keduanya sama dalam kedua kasus dan merupakan nilai yang diberi nama pertama berdasarkan abjad.


Tapi ada solusinya. Dari contoh kode awal Anda, yang saya kumpulkan adalah Anda memerlukan daftar Enum, deskripsinya, dan nilai numeriknya, benarkah? Jadi, pertama-tama saya akan mengambil daftar string tidak termasuk Default yang cukup sederhana. Kemudian ulangi daftar string, dan tambahkan ke daftar objek kelas SelectListItem Anda.

var res = Enum.GetNames(typeof(Fruits))
    .Where(x => x != "Default");

List<SelectListItem> list = new List<SelectListItem>();
foreach (string fruit in res)
{
    string desc = EnumHelper<Fruits>.GetEnumDescription(fruit); // This is a utility method I use. You can get the description using your extension method.
    int val = (int)Enum.Parse(typeof(Fruits), fruit);
    list.Add(new SelectListItem { enumName = fruit, enumDesc = desc, enumVal = val });
}

Dan jika Anda harus memiliki OrderBy itu, setelah membuat daftar SelectListItem Anda, urutkan sekali lagi berdasarkan Description.

person Sach    schedule 16.08.2017
comment
Anda memiliki keluaran yang berbeda saat menggunakan Peaches = Default , Default = 1, dan Default = Peaches, Peaches = 1, karena Anda memanggil Enum.ToString di Console.WriteLine. Jika Anda melihat var deflt, var peach Anda akan melihat bahwa keduanya sama dalam kedua kasus dan keduanya adalah nilai yang namanya berada di urutan pertama berdasarkan abjad - person George Alexandria; 16.08.2017
comment
Itu menarik untuk diketahui! Terima kasih! Saya akan memperbarui jawaban saya dengan informasi ini. - person Sach; 16.08.2017
comment
enum sudah digunakan dan tidak dapat diubah. ditambah lagi tidak masuk akal untuk mengubah enum seperti itu.. alasan penggunaan default, saya percaya pada kode yang ada adalah memiliki cara mudah untuk mengubah default jika perlu. namun nilai dari nilai-nilai yang ada tidak bisa diubah. jadi membuat peach = default, adalah perbedaan besar dibandingkan mengatakan default = peach. Jadi tidak ada cara untuk menyelesaikan ini selain dengan solusi Anda? Hmm - person user1161137; 17.08.2017
comment
@Sach bagaimana cara agar metode ekstensi berfungsi menggantikan apa yang Anda tulis untuk mendapatkan deskripsi. artinya, tidak ada enum cara Anda melakukannya, jadi bagaimana deskripsi ekstensi yang saya miliki dapat digunakan. mengacu pada baris ini: string desc = EnumHelper‹Fruits›.GetEnumDescription(fruit); - person user1161137; 17.08.2017
comment
Saya berasumsi Anda memiliki metode penyuluhan sendiri, yang merupakan apa yang Anda katakan sebagai tanggapan terhadap salah satu komentar saya sebelumnya. Saya tidak yakin tentang metode ekstensi, namun Anda boleh menggunakan metode utilitas yang biasa saya gunakan, yang awalnya saya peroleh dari jawaban SO juga. - person Sach; 17.08.2017
comment
ya itu adalah metode penyuluhan. tapi itu memperluas tipe enum. saya hanya tidak tahu bagaimana memasukkannya ke dalam solusi Anda. sebelum saya melakukannya di predikat yang mengambil tipe enum. tetapi yang Anda miliki di sana adalah string yang sedang Anda kerjakan. - person user1161137; 17.08.2017
comment
Anda sebenarnya tidak membutuhkan metode penyuluhan. Panggil saja metode utilitas yang saya berikan seperti ini: string desc = EnumHelper<Fruits>.GetEnumDescription(fruit); - person Sach; 17.08.2017
comment
masih mengalami kesulitan untuk memasukkannya ke daftar dropdown. Apakah ada pendekatan alternatif untuk menambahkan anotasi Atribut ke Enum sehingga dapat DIKECUALIKAN dari Pilihan? Sepertinya itu cara yang lebih baik. - person user1161137; 17.08.2017
comment
Masalah apa yang kamu punya? Karena kode ini, pada akhirnya, melakukan persis seperti yang Anda lakukan pada awalnya, karena kode ini membuat daftar objek SelectListItem. - person Sach; 17.08.2017
comment
saya mencoba solusi Anda, dan saya masih mendapatkan default dalam daftar. - person user1161137; 17.08.2017
comment
@ user1161137 itu tidak mungkin. Inilah keseluruhan kode yang saya jalankan dan menghasilkan hasil yang diharapkan dengan baik. dotnetfiddle.net/GFcklC - person Sach; 17.08.2017
comment
ya, saya melihat contoh Anda berfungsi... secara keseluruhan proses ini tampaknya sangat tidak stabil, karena segera setelah Anda memindahkan enum (posisi dalam daftar) atau memperkenalkan enum tambahan (dengan nilai unik), proses tersebut akan rusak. Saya akan menambahkan enum buah lain ke deskripsi... untuk membuktikan maksud saya... namun solusi Anda akan berhasil, karena ini hanya tentang menghilangkan enum default, tetapi ternyata tidak. - person user1161137; 18.08.2017
comment
tidak mengerti... baru saja melihat sampel Anda dan saya melihat default di daftar keluaran. terima kasih atas bantuanmu btw.. aku tahu ini menyita waktumu. - person user1161137; 18.08.2017
comment
saya melihat Anda menghapus komentar Anda yang menunjukkan sampel kedua... jadi saya kira Anda mengonfirmasi bahwa itu tidak berfungsi juga. - person user1161137; 18.08.2017
comment
Ya itu tidak berhasil untuk beberapa orang dan berhasil untuk orang lain. Dan saya pikir masalah sebenarnya adalah kesetaraan dalam enum Anda, dan itu menjadi kacau ketika metode Parse() digunakan. Bolehkah saya bertanya mengapa Anda menginginkan kesetaraan itu? Anda akan lebih baik jika menggunakan enum yang bersih. - person Sach; 18.08.2017
comment
untuk kenyamanan dalam kode di mana saat ini ketika kode terkena, nilai tertentu tersebut digunakan.. karena di masa mendatang, nilai lain dapat digunakan sebagai 'default' dan Anda tidak ingin harus melalui semua lokasi dalam kode untuk memperbarui nilai default baru yang seharusnya. itu digunakan di banyak tempat seperti itu. - person user1161137; 18.08.2017
comment
oke, sepertinya berhasil jika Anda mengganti baris .Where(x =› x != Fruits.Default.ToString()); dengan suhu = Default; var res = Enum.GetNames(typeof(Buah)); res = res.Di mana(e =› e != temp).ToArray(); daripada mendapatkan kunci default dari enum, kita sudah tahu itu adalah default yang ingin kita hapus, jadi secara eksplisit memasukkannya ke dalam string memastikan kita berurusan dengan nama enum yang benar... maka sisa kode Anda berfungsi. - person user1161137; 18.08.2017
comment
@Sach perbarui jawaban Anda menjadi string literal 'Default' daripada bergantung pada Fruits.Default.ToString() ... dan saya akan menerima jawabannya. - person user1161137; 18.08.2017
comment
Selesai. Namun menurut saya struktur enum Anda masih rentan terhadap banyak konsekuensi yang tidak diinginkan, dan harus dihindari jika memungkinkan. - person Sach; 18.08.2017
comment
juga.. Anda harus menambahkan Enum Helper itu ke jawabannya jika ada orang lain yang membutuhkannya. tidak ada jaminan bahwa bagian itu akan tersedia di masa mendatang jika bukan bagian dari jawaban ini. - person user1161137; 19.08.2017

Anda harus membandingkan nilai enum berdasarkan namanya, karena Default dan Banana sama. Jadi coba saja ambil nama, filter, dan parsing menjadi nilai.

var res = Enum.GetNames(typeof(Fruits))
              .Where(o => o != nameof(Fruits.Default))
              .Select(o => Enum.Parse(typeof(Fruits), o))
              .Cast<Fruits>().ToList();

Ini contoh lengkap Anda:

Html.DropDownList("fruitSelector",
            Enum.GetNames(typeof(Fruits))
                .Where(o => o != nameof(Fruits.Default))
                .Select(o => Enum.Parse(typeof(Fruits), o)).Cast<Fruits>()
                .OrderBy(o => o.GetDescription())
                .Select(o => new SelectListItem() { Text = o.GetDescription(), Value = ((int)o).ToString() }), "-- All Fruits --",
            new { @class = "form-control", @aria_describedby = "sizing-addon1" })
person George Alexandria    schedule 15.08.2017
comment
yang tampaknya berfungsi pada enum pertama yang saya masukkan... tetapi saya perhatikan bahwa enum itu tidak mereplikasi masalah saya... saya menambahkan enum kedua yang sedikit berbeda... tetapi merusak solusi Anda. sejujurnya aku tidak mengerti kenapa. Terima kasih atas bantuan Anda - person user1161137; 16.08.2017
comment
solusi ini memberikan, apel, pisang, jeruk bali, default, semangka... jadi buah persik tidak muncul tetapi default muncul. - person user1161137; 16.08.2017
comment
@ user1161137 Enum pertama Anda berfungsi karena Banane lebih kecil menurut abjad daripada Default, tetapi Peaches lebih besar dari Default, jadi ketika Anda mencoba mengurai 1, Parse mengembalikan nilai lebih kecil berdasarkan nama . Untuk enum kedua adalah Default - person George Alexandria; 16.08.2017
comment
@ user1161137 Jika Anda mencari solusi untuk enum kedua, Anda dapat mencoba solusinya di jawaban Sach. - person George Alexandria; 17.08.2017
comment
Ya, enum kedua adalah apa yang saya hadapi.. saya hanya tidak menerjemahkan masalah dengan benar ke tumpukan. Saya tidak berurusan dengan buah-buahan :-) - person user1161137; 17.08.2017