प्रदर्शन मायने रखता है
यदि आप बेहतर प्रदर्शन चाहते हैं तो यह रास्ता है:
public static class AdvancedEnumExtensions
{
/// <summary>
/// Gets the custom attribute <typeparamref name="T"/> for the enum constant, if such a constant is defined and has such an attribute; otherwise null.
/// </summary>
public static T GetCustomAttribute<T>(this Enum value) where T : Attribute
{
return GetField(value)?.GetCustomAttribute<T>(inherit: false);
}
/// <summary>
/// Gets the FieldInfo for the enum constant, if such a constant is defined; otherwise null.
/// </summary>
public static FieldInfo GetField(this Enum value)
{
ulong u64 = ToUInt64(value);
return value
.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
.Where(f => ToUInt64(f.GetRawConstantValue()) == u64)
.FirstOrDefault();
}
/// <summary>
/// Checks if an enum constant is defined for this enum value
/// </summary>
public static bool IsDefined(this Enum value)
{
return GetField(value) != null;
}
/// <summary>
/// Converts the enum value to UInt64
/// </summary>
public static ulong ToUInt64(this Enum value) => ToUInt64((object)value);
private static ulong ToUInt64(object value)
{
switch (Convert.GetTypeCode(value))
{
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
return unchecked((ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture));
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Char:
case TypeCode.Boolean:
return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
default: throw new InvalidOperationException("UnknownEnumType");
}
}
}
इसका प्रदर्शन बेहतर क्यों है?
क्योंकि बिल्ट-इन मेथड्स कोड के समान ही उपयोग करते हैं, सिवाय इसके कि वे अन्य कोड का एक समूह भी चलाते हैं जिनकी हमें परवाह नहीं है । C # का Enum कोड सामान्य रूप से काफी भयानक है।
उपरोक्त कोड Linq-ified और सुव्यवस्थित किया गया है, इसलिए इसमें केवल वे बिट्स होते हैं जिनकी हम परवाह करते हैं।
अंतर्निहित कोड धीमा क्यों है?
सबसे पहले Enum.ToString () -vs- Enum.GetName (..) के बारे में
हमेशा बाद का उपयोग करें। (या बेहतर अभी तक न तो, जैसा कि नीचे स्पष्ट हो जाएगा।)
ToString () आंतरिक रूप से उत्तरार्द्ध का उपयोग करता है, लेकिन फिर से, अन्य सामानों का एक गुच्छा भी करता है जो हम नहीं चाहते हैं, उदाहरण के लिए झंडे को जोड़ने की कोशिश करता है, संख्याओं का प्रिंट आउट करता है आदि हम केवल एनम के अंदर परिभाषित स्थिरांक में रुचि रखते हैं।
Enum.GetName बदले में सभी फ़ील्ड प्राप्त करता है, सभी नामों के लिए एक स्ट्रिंग ऐरे बनाता है, उपरोक्त सभी TOUInt64 का उपयोग करता है अपने सभी RawConstantValues पर सभी मानों का एक UInt64 सरणी बनाने के लिए, दोनों ऐरे को UInt64 मान के अनुसार क्रमबद्ध करता है, और अंत में नाम प्राप्त करता है। नाम-सरणी हमें UInt64-array में एक बाइनरीसर्च करके उस मान के सूचकांक को खोजने के लिए करता है जिसे हम चाहते थे।
... और फिर हम खेतों को फेंक देते हैं और हल किए गए सरणियों को उस नाम का उपयोग करके फिर से फ़ील्ड ढूंढते हैं।
एक शब्द: "उघ!"