วิธีใดที่ต้องการแปลง Enum เป็น String ใน. NET 3.5
- Enum.GetName
- Enum.Format
- ToString
เหตุใดฉันจึงควรเลือกหนึ่งในสิ่งเหล่านี้เหนือสิ่งอื่นใด มันทำงานได้ดีขึ้นหรือไม่
วิธีใดที่ต้องการแปลง Enum เป็น String ใน. NET 3.5
เหตุใดฉันจึงควรเลือกหนึ่งในสิ่งเหล่านี้เหนือสิ่งอื่นใด มันทำงานได้ดีขึ้นหรือไม่
คำตอบ:
ในฐานะของ C # 6 วิธีที่ดีที่สุดในการรับชื่อของ enum คือnameof
โอเปอเรเตอร์ใหม่:
nameof(MyEnum.EnumValue);
// Ouputs
> "EnumValue"
สิ่งนี้ทำงานได้ในเวลารวบรวมโดยการแทนที่ enum ด้วยสตริงในผลลัพธ์ที่คอมไพล์ซึ่งหมายความว่านี่เป็นวิธีที่เร็วที่สุดที่เป็นไปได้
การใช้ชื่อ enum ใด ๆ จะรบกวนการทำให้งงงวยของรหัสถ้าคุณคิดว่าการทำให้งอแงของชื่อ Enum นั้นมีความคุ้มค่าหรือสำคัญ - นั่นอาจเป็นคำถามอื่นทั้งหมด
nameof(variableEnum)
ไป"variableEnum"
ได้ มันสะท้อนให้เห็นถึง (เวลาที่สร้าง) ชื่อของสนาม / คุณสมบัติ / พระราม / ตัวแปรไม่คุ้มค่า
"someEnumValue"
ในขณะที่คุณจะต้องที่จะได้รับnameof(SomeEnum.FooBar)
"FooBar"
ทำงานให้กับโครงการของเรา ...
public static String convertToString(this Enum eff)
{
return Enum.GetName(eff.GetType(), eff);
}
public static EnumType converToEnum<EnumType>(this String enumValue)
{
return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}
ในการทดสอบของฉันEnum.GetName
เร็วขึ้นและมีอัตรากำไรที่เหมาะสม ภายในสายToString
จากแหล่งที่มาสำหรับ. NET 4.0 สิ่งสำคัญ:Enum.GetName
public override String ToString()
{
return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}
private static String InternalFormat(RuntimeType eT, Object value)
{
if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
{
String retval = GetName(eT, value); //<== the one
if (retval == null)
return value.ToString();
else
return retval;
}
else
{
return InternalFlagsFormat(eT, value);
}
}
ฉันไม่สามารถบอกได้ว่าเป็นเหตุผลที่แน่นอน แต่การทดสอบสถานะนั้นเร็วกว่าอีกอัน การโทรทั้งสองนี้เกี่ยวข้องกับการชกมวย (อันที่จริงแล้วพวกมันคือการสะท้อนการโทร
การตั้งค่าการทดสอบ : enum ด้วยค่า 8 ค่าหมายเลข จากการวนซ้ำ = 1000000
ผลลัพธ์ : Enum.GetName => 700 ms, ToString => 2000 ms
หากความเร็วไม่ชัดเจนฉันจะไม่แคร์และใช้ToString
เนื่องจากมันมีสายที่สะอาดกว่ามาก ความคมชัด
Enum.GetName(typeof(Bla), value)
กับ
value.ToString()
นี่เป็นวิธีที่หรูหราที่สุดที่มีไว้สำหรับมัน
var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);
แม้ว่าฉันจะไม่เห็นปัญหาใด ๆ กับการโทร.ToString()
เพราะสั้นกว่า
var enumValueString = MyEnum.MyValue.ToString();
ด้วยไวยากรณ์ C # 6 ใหม่คุณสามารถใช้:
nameof(MyEnum.MyValue)
InternalGetValueAsString
ทั้งหมดเหล่านี้ภายในสิ้นสุดการเรียกวิธีการที่เรียกว่า ความแตกต่างระหว่างToString
และGetName
จะต้องGetName
มีการตรวจสอบบางสิ่งก่อน:
GetType
กับค่าในการตรวจสอบนี้.ToString
ไม่ต้องกังวลเกี่ยวกับปัญหาใด ๆ ข้างต้นเพราะมันถูกเรียกบนอินสแตนซ์ของคลาสเองและไม่ใช่ในเวอร์ชันที่ส่งผ่านดังนั้นเนื่องจากความจริงที่ว่า.ToString
วิธีการไม่มีปัญหาการตรวจสอบที่เหมือนกัน เป็นวิธีคงที่ฉันจะสรุปว่า.ToString
เป็นวิธีที่เร็วที่สุดเพื่อให้ได้ค่าเป็นสตริง
ดีที่สุดที่ฉันสามารถหาได้คือคำถามที่ไม่เกี่ยวข้องใน MSDNซึ่งมีข้อมูลโค้ด XML ที่ตอบคำถามนี้ ใด ๆ ของวิธีการเหล่านี้ส่วนใหญ่มีข้อบกพร่องเดียวกันพวกเขาเรียกenum.toString()
ที่ไม่ได้ทำงานอย่างถูกต้องเมื่อใช้Dotfuscation ความกังวลอื่น ๆ ดูเหมือนจะเกี่ยวข้องกับการชกมวยทางอ้อม (GetName และ Format) น่าเสียดายที่ฉันไม่สามารถหาเหตุผลด้านประสิทธิภาพใด ๆ สำหรับการใช้ข้อใดข้อหนึ่งข้างต้น
ถอดความจากตัวอย่าง XML ,
การส่งผ่าน enum ชนิดบรรจุกล่องไปยัง string รูปแบบ () หรือฟังก์ชันอื่น ๆ อาจส่งผลให้เกิด
enum.ToString()
การเรียกใช้ สิ่งนี้จะทำให้เกิดปัญหาเมื่อ Dotfuscating คุณไม่ควรใช้enum.ToString()
,enum.GetNames()
,enum.GetName()
,enum.Format()
หรือenum.Parse()
การแปลง enum สตริง ให้ใช้คำสั่ง switch และแทนชื่อสากลหากจำเป็น
Enum.GetName()
Format()
จริงๆแล้วมันเป็นเพียงแค่ wrapper ที่GetName()
มีฟังก์ชั่นการจัดรูปแบบบางอย่าง (หรือInternalGetValueAsString()
แน่นอน) สวยมากเช่นเดียวกับToString()
Format()
ฉันคิดว่าGetName()
เป็นตัวเลือกที่ดีที่สุดเพราะเห็นได้ชัดว่ามันทำอะไรกับทุกคนที่อ่านต้นฉบับ
ฉันสร้างวิธีการส่วนขยาย "คำอธิบาย" และแนบกับ enum เพื่อที่ฉันจะได้รับการตั้งชื่อที่ใช้งานง่ายอย่างแท้จริงซึ่งมีช่องว่างและปลอก ฉันไม่เคยชอบใช้ค่า enum เป็นข้อความที่แสดงได้เนื่องจากเป็นสิ่งที่นักพัฒนาซอฟต์แวร์ใช้ในการสร้างโค้ดที่อ่านได้มากขึ้น มันไม่ได้มีไว้สำหรับการแสดงผล UI ฉันต้องการที่จะสามารถเปลี่ยน UI โดยไม่ต้องผ่านและเปลี่ยน enums ทั้งหมด
ฉันไม่ทราบว่าวิธี "ที่ต้องการ" คืออะไร (ถาม 100 คนและรับความคิดเห็นที่แตกต่างกัน 100 ข้อ) แต่ทำในสิ่งที่ง่ายที่สุดและใช้งานได้ดี GetName
ทำงานได้ แต่ต้องใช้การกดแป้นมากขึ้น ToString()
ดูเหมือนว่าจะทำงานได้ดีมาก
สำหรับผู้สนใจรัก VB:
EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue)
มันก็ใช้ได้เหมือนกัน
List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();
ToString()
ให้ผลลัพธ์ที่ชัดเจนที่สุดจากมุมมองที่อ่านได้ในขณะที่ใช้Enum.GetName()
ต้องมีการแยกวิเคราะห์ทางจิตมากกว่าเล็กน้อยเพื่อให้เข้าใจได้อย่างรวดเร็วว่ามันพยายามทำอะไร (เว้นแต่คุณจะเห็นรูปแบบตลอดเวลา)
จากมุมมองประสิทธิภาพบริสุทธิ์ตามที่ระบุไว้แล้วในคำตอบของ @ nawfal Enum.GetName()
จะดีกว่า
หากประสิทธิภาพเป็นเป้าหมายของคุณจริง ๆ มันจะเป็นการดียิ่งขึ้นหากต้องการค้นหาล่วงหน้า (โดยใช้พจนานุกรมหรือการทำแผนที่อื่น ๆ )
ใน C ++ / CLI นี้จะมีลักษณะ
Dictionary<String^, MyEnum> mapping;
for each (MyEnum field in Enum::GetValues(MyEnum::typeid))
{
mapping.Add(Enum::GetName(MyEnum::typeid), field);
}
การเปรียบเทียบโดยใช้ enum 100 รายการและการทำซ้ำ 1000000 รายการ:
Enum.GetName: ~ 800ms
. ToString (): ~ 1600ms
การทำแผนที่พจนานุกรม: ~ 250ms
แบบง่าย: ระบุชื่อลงในรายการ:
List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()