ชื่อ c# enum ที่จะกรองใน DropDownList แทนที่จะเป็นค่า

ฉันมีรายการแจงนับที่มีการแจงนับที่เรียกว่าค่าเริ่มต้น

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

ฉันต้องเติมรายการดรอปดาวน์ที่ไม่รวมฟิลด์เริ่มต้น

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"})

เมื่อฉันพยายามกรอง Fruits.Default มันจะลบทั้งค่าเริ่มต้นและ Banana ฉันจะทำการเปรียบเทียบตัวกรองโดยที่ฉันลบเฉพาะค่าเริ่มต้นได้อย่างไร

[[การแก้ไข]] แจงนับนี้ซ้ำกับปัญหาของฉัน ฉันไม่เข้าใจความแตกต่างจริงๆ

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 แหล่งที่มา
comment
โค้ดข้างต้นคอมไพล์หรือไม่ หรือคุณมีวิธีการขยายที่ไม่แสดงที่นี่? มิฉะนั้น o.GetDescription() จะคอมไพล์โดยไม่มีข้อผิดพลาดได้อย่างไร   -  person Sach    schedule 16.08.2017
comment
stackoverflow.com/questions/30467519/   -  person Dan Orlovsky    schedule 16.08.2017
comment
@Sach ya นั่นคือวิธีการรับคำอธิบายประกอบคำอธิบายที่กำหนดเอง คุณสามารถยกเว้นสิ่งนั้นได้   -  person user1161137    schedule 16.08.2017


คำตอบ (2)


ฉันไม่คิดว่าสิ่งที่คุณพยายามทำจะเป็นไปได้ อย่างที่มันเป็น ปัญหาคือโครงสร้าง Enum ของคุณ

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

คุณกำลังบอกว่าค่าของ Default คือ Peaches ซึ่งค่าในทางกลับกันคือ 1 ซึ่งโดยพื้นฐานแล้วจะเหมือนกับ (B คือ Peaches และ A คือ Default:

int B = 1;
int A = B;

ดังนั้นเมื่อเราใช้ Enum.Parse() มันจะถือว่าทั้งสองเหมือนกัน และเลือกค่าแรก คุณจะเข้าใจเมื่อคุณดูสถานการณ์ต่อไปนี้ รันโค้ดต่อไปนี้ด้วย Enum ปัจจุบันของคุณ:

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

ผลลัพธ์จะเป็น:

ค่าเริ่มต้น

ค่าเริ่มต้น

จากนั้นเปลี่ยน Enum ของคุณเป็น:

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

และรันโค้ดสองบรรทัดด้านบนอีกครั้ง ผลลัพธ์ของคุณในครั้งนี้จะเป็น:

ลูกพีช

ลูกพีช

นั่นคือ Parse() เลือก Enum ที่กำหนดไว้เป็นอันดับแรกเมื่อมีความเท่าเทียมกันเหมือนกับที่คุณมี

แก้ไข:

คำอธิบายข้างต้นไม่ถูกต้องเล็กน้อย ดังที่ George Alexandria ระบุไว้ในความคิดเห็นด้านล่าง โปรดดูคำอธิบายของเขา: คุณมีเอาต์พุตที่แตกต่างกันเมื่อใช้ Peaches = Default , Default = 1 และ Default = Peaches, Peaches = 1 เนื่องจากคุณเรียกใช้ Enum.ToString ใน Console.WriteLine หากคุณดูที่ var deflt, var Peach คุณจะเห็นว่าทั้งสองกรณีเหมือนกันและเป็นค่าที่ชื่อขึ้นต้นตามตัวอักษร


แต่มีวิธีแก้ไขคือ จากตัวอย่างโค้ดเริ่มต้นของคุณ สิ่งที่ฉันรวบรวมคือคุณต้องการรายการ Enums คำอธิบาย และค่าตัวเลข ฉันถูกต้องหรือไม่ ก่อนอื่นฉันจะหยิบรายการ strings ยกเว้น Default ซึ่งค่อนข้างง่าย จากนั้นวนซ้ำรายการสตริง และเพิ่มไปยังรายการออบเจ็กต์คลาส SelectListItem ของคุณ

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

และหากคุณ ต้อง มี OrderBy หลังจากสร้างรายการ SelectListItem ของคุณแล้ว ให้จัดเรียงอีกครั้งด้วย Description

person Sach    schedule 16.08.2017
comment
คุณมีผลลัพธ์ที่แตกต่างกันเมื่อใช้ Peaches = Default , Default = 1, และ Default = Peaches, Peaches = 1, เนื่องจากคุณเรียกใช้ Enum.ToString ใน Console.WriteLine หากคุณดูที่ var deflt, var peach คุณจะเห็นว่าทั้งสองกรณีเหมือนกันและเป็นค่าที่ ชื่อขึ้นต้นด้วยตัวอักษร - person George Alexandria; 16.08.2017
comment
เป็นเรื่องที่น่าสนใจที่จะรู้! ขอบคุณ! ฉันจะอัปเดตคำตอบด้วยข้อมูลนี้ - person Sach; 16.08.2017
comment
enum มีการใช้งานอยู่แล้วและไม่สามารถเปลี่ยนแปลงได้ แถมยังไม่สมเหตุสมผลเลยที่จะเปลี่ยน enum แบบนั้น .. เหตุผลที่ใช้ค่าเริ่มต้นฉันเชื่อในรหัสที่มีอยู่คือการมีวิธีที่ง่ายในการเปลี่ยนค่าเริ่มต้นหากจำเป็น แต่ค่าของค่าที่มีอยู่ไม่สามารถเปลี่ยนแปลงได้ ดังนั้นการทำให้พีช = ค่าเริ่มต้น แตกต่างอย่างมากจากการพูดว่า default = พีช ดังนั้นจึงไม่มีทางที่จะทำสิ่งนี้ให้สำเร็จได้นอกจากวิธีแก้ปัญหาของคุณ? อืม - person user1161137; 17.08.2017
comment
@Sach ฉันจะทำให้วิธีการขยายทำงานแทนสิ่งที่คุณเขียนเพื่อรับคำอธิบายได้อย่างไร หมายความว่าไม่มีแจงนับแบบที่คุณทำ ดังนั้นคำอธิบายส่วนขยายที่ฉันมีอยู่จะนำไปใช้ได้อย่างไร อ้างถึงบรรทัดนี้: string desc = EnumHelper‹Fruits›.GetEnumDescription(fruit); - person user1161137; 17.08.2017
comment
ฉันคิดว่าคุณมีวิธีการขยายของคุณเอง ซึ่งเป็นสิ่งที่คุณพูดเพื่อตอบสนองต่อความคิดเห็นก่อนหน้านี้ของฉัน ฉันไม่แน่ใจเกี่ยวกับวิธีการขยาย แต่คุณสามารถใช้ วิธีการอรรถประโยชน์ที่ฉันมักจะใช้ ซึ่งฉันได้รับมาจากคำตอบ SO เช่นกัน - person Sach; 17.08.2017
comment
ใช่ มันเป็นวิธีการขยาย แต่จะขยายประเภทแจงนับ ฉันแค่ไม่รู้ว่าจะใส่มันลงในโซลูชันของคุณได้อย่างไร ก่อนที่ฉันจะทำมันในภาคแสดงที่ใช้ประเภทแจงนับ แต่สิ่งที่คุณมีนั้นมีสตริงที่คุณกำลังใช้งานอยู่ - person user1161137; 17.08.2017
comment
คุณไม่จำเป็นต้อง ต้องการ วิธีการขยายจริงๆ เพียงเรียกวิธีการอรรถประโยชน์ที่ฉันให้ไว้ดังนี้: string desc = EnumHelper<Fruits>.GetEnumDescription(fruit); - person Sach; 17.08.2017
comment
ยังคงมีปัญหาในการนำมันเข้าไปในรายการดรอปดาวน์ มีแนวทางอื่นในการเพิ่มคำอธิบายประกอบแอตทริบิวต์ให้กับ Enum เพื่อให้สามารถแยกออกจากส่วนที่เลือกได้หรือไม่ ดูเหมือนว่าจะเป็นวิธีที่ดีกว่า - person user1161137; 17.08.2017
comment
คุณมีปัญหาอะไร? เพราะท้ายที่สุดแล้วโค้ดนี้ก็จะทำตามสิ่งที่คุณทำตั้งแต่แรกอย่างแน่นอน เนื่องจากโค้ดนี้จะสร้างรายการของอ็อบเจ็กต์ SelectListItem - person Sach; 17.08.2017
comment
ฉันลองวิธีแก้ปัญหาของคุณแล้ว และฉันยังคงได้รับค่าเริ่มต้นอยู่ในรายการ - person user1161137; 17.08.2017
comment
@ user1161137 นั่นเป็นไปไม่ได้ นี่คือโค้ด ทั้งหมด ที่ฉันเรียกใช้ และให้ผลลัพธ์ที่คาดหวังได้ดี dotnetfiddle.net/GFcklC - person Sach; 17.08.2017
comment
ใช่ ฉันเห็นตัวอย่างของคุณใช้งานได้... โดยรวมแล้วกระบวนการนี้ดูไม่สม่ำเสมอมาก เพราะทันทีที่คุณย้าย enum ไปรอบๆ (ตำแหน่งในรายการ) หรือแนะนำ enum เพิ่มเติม (ด้วยค่าที่ไม่ซ้ำกัน) กระบวนการก็จะพัง ฉันจะเพิ่ม enum ผลไม้อื่นในคำอธิบาย... เพื่อพิสูจน์ประเด็นของฉัน... แต่วิธีแก้ปัญหาของคุณควรใช้งานได้ เพราะมันเป็นเพียงการกำจัด enum เริ่มต้น แต่ก็ไม่ได้ผล - person user1161137; 18.08.2017
comment
ไม่เข้าใจ... แค่ดูตัวอย่างของคุณและฉันเห็นค่าเริ่มต้นในรายการผลลัพธ์ ขอบคุณสำหรับความช่วยเหลือของคุณ .. ฉันรู้ว่านี่ต้องใช้เวลาของคุณ - person user1161137; 18.08.2017
comment
ฉันเห็นคุณลบความคิดเห็นของคุณที่แสดงตัวอย่างที่สอง... ดังนั้นฉันคิดว่าคุณยืนยันว่ามันไม่ได้ผลเช่นกัน - person user1161137; 18.08.2017
comment
ใช่ มันไม่ได้ผลสำหรับบางคนและใช้ได้กับคนอื่นๆ และฉันคิดว่าปัญหาที่แท้จริงคือความเท่าเทียมกันในแจงนับของคุณ และทำให้เกิดปัญหาเมื่อใช้เมธอด Parse() ฉันขอถามว่าทำไมคุณถึงต้องการความเท่าเทียมกันนั้น? คุณจะดีกว่าถ้าคุณใช้ clean enum - person Sach; 18.08.2017
comment
เพื่อความสะดวกในการเขียนโค้ด โดยที่ปัจจุบันเมื่อโดนโค้ดแล้วจะใช้ค่านั้น.. เพราะในอนาคตค่าอื่นอาจใช้เป็น 'ค่าเริ่มต้น' ได้ และคุณไม่ต้องการผ่านทุกตำแหน่ง ในโค้ดเพื่ออัปเดตค่าเริ่มต้นใหม่ที่ควรเป็น มันใช้ในหลายๆ ที่แบบนั้น - person user1161137; 18.08.2017
comment
ตกลงดูเหมือนว่าจะใช้งานได้หากคุณแทนที่บรรทัด .Where(x =› x != Fruits.Default.ToString()); ด้วยอุณหภูมิ = ค่าเริ่มต้น; var res = Enum.GetNames (ประเภทของ (ผลไม้)); res = res.Where(e =› e != temp).ToArray(); แทนที่จะรับคีย์เริ่มต้นจาก enum เรารู้อยู่แล้วว่ามันเป็นค่าเริ่มต้นที่เราต้องการลบ ดังนั้นการใส่คีย์นั้นลงในสตริงอย่างชัดเจนทำให้มั่นใจได้ว่าเรากำลังจัดการกับ enum ที่มีชื่อถูกต้อง... จากนั้นโค้ดที่เหลือก็จะใช้งานได้ - person user1161137; 18.08.2017
comment
@Sach อัปเดตคำตอบของคุณเป็นสตริงตัวอักษร 'Default' แทนที่จะขึ้นอยู่กับ Fruits.Default.ToString() ... และฉันจะยอมรับคำตอบ - person user1161137; 18.08.2017
comment
เสร็จแล้ว. แต่ฉันยังคงคิดว่าโครงสร้าง enum ของคุณเสี่ยงต่อผลที่ตามมามากมายโดยไม่ได้ตั้งใจ และควรหลีกเลี่ยงหากเป็นไปได้ - person Sach; 18.08.2017
comment
ด้วย .. คุณควรเพิ่ม Enum Helper นั้นในคำตอบในกรณีที่คนอื่นต้องการสิ่งนี้ ไม่รับประกันว่าส่วนนั้นจะมีให้ในอนาคตหากไม่ใช่ส่วนหนึ่งของคำตอบนี้ - person user1161137; 19.08.2017

คุณควรเปรียบเทียบค่าแจงนับด้วยชื่อ เนื่องจาก Default และ Banana เท่ากัน ดังนั้นลองดึงชื่อ กรอง และแยกวิเคราะห์เป็นค่าต่างๆ

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

นี่คือตัวอย่างเต็มของคุณ:

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
ที่ดูเหมือนว่าจะใช้ได้กับ enum แรกที่ฉันใส่เข้าไป ... แต่ฉันสังเกตเห็นว่า enum นั้นไม่ได้จำลองปัญหาของฉัน ... ฉันเพิ่ม enum ตัวที่สองซึ่งแตกต่างออกไปเล็กน้อย ... แต่ทำให้วิธีแก้ปัญหาของคุณพัง ฉันไม่เข้าใจจริงๆว่าทำไม ขอบคุณสำหรับความช่วยเหลือของคุณ - person user1161137; 16.08.2017
comment
วิธีแก้ปัญหานี้ให้, แอปเปิ้ล, กล้วย, ส้มโอ, ค่าเริ่มต้น, แตงโม... ดังนั้นลูกพีชจึงไม่ปรากฏขึ้น แต่ค่าเริ่มต้นจะแสดง - person user1161137; 16.08.2017
comment
@ user1161137 ก่อนอื่นคุณแจงนับใช้งานได้เพราะ Banane น้อยกว่าตามตัวอักษรนั้น Default แต่ Peaches มากกว่านั้น Default ดังนั้นเมื่อคุณพยายามแยกวิเคราะห์ 1 Parse จะส่งกลับค่าน้อยกว่าตามชื่อ . สำหรับแจงนับที่สองคือ Default - person George Alexandria; 16.08.2017
comment
@ user1161137 หากคุณกำลังมองหาวิธีแก้ปัญหาสำหรับ enum ที่สอง คุณสามารถลองวิธีแก้ปัญหาในคำตอบ Sach - person George Alexandria; 17.08.2017
comment
ใช่ enum ที่สองคือสิ่งที่ฉันกำลังเผชิญอยู่ .. ฉันแค่แปลปัญหาไม่ถูกต้องเพื่อสแต็ก ฉันไม่ได้เกี่ยวข้องกับผลไม้ :-) - person user1161137; 17.08.2017