उपरोक्त समाधान [Flags]
स्थितियों से नहीं निपटते हैं ।
नीचे दिए गए मेरे समाधान में कुछ प्रदर्शन समस्याएँ हो सकती हैं (मुझे यकीन है कि एक व्यक्ति विभिन्न तरीकों से अनुकूलन कर सकता है) लेकिन अनिवार्य रूप से यह हमेशा साबित होगा कि एक एनम मान मान्य है या नहीं ।
यह तीन मान्यताओं पर निर्भर करता है:
- C # में Enum मान केवल
int
, कुछ और नहीं, की अनुमति है
- C # में Enum नाम अक्षर वर्ण से शुरू होना चाहिए
- कोई वैध ईनाम नाम माइनस साइन के साथ नहीं हो सकता है:
-
किसी एनम (ध्वज या नहीं) का मिलान नहीं होने ToString()
पर, एनम पर कॉल करना या तो int
मान देता है। यदि एक अनुमत एनम मूल्य का मिलान किया जाता है, तो यह मैच के नाम को प्रिंट करेगा (तों)।
इसलिए:
[Flags]
enum WithFlags
{
First = 1,
Second = 2,
Third = 4,
Fourth = 8
}
((WithFlags)2).ToString() ==> "Second"
((WithFlags)(2 + 4)).ToString() ==> "Second, Third"
((WithFlags)20).ToString() ==> "20"
इन दो नियमों को ध्यान में रखते हुए, हम यह मान सकते हैं कि यदि .NET फ्रेमवर्क अपना काम सही ढंग से करता है, तो वैध एनुम के किसी भी कॉल के ToString()
परिणामस्वरूप कुछ ऐसा होगा, जिसमें वर्णमाला का पहला वर्ण होता है:
public static bool IsValid<TEnum>(this TEnum enumValue)
where TEnum : struct
{
var firstChar = enumValue.ToString()[0];
return (firstChar < '0' || firstChar > '9') && firstChar != '-';
}
कोई इसे "हैक" कह सकता है, लेकिन लाभ यह है कि Microsoft के स्वयं के कार्यान्वयन पर Enum
और C # मानकों पर भरोसा करके, आप अपने स्वयं के संभावित छोटी गाड़ी कोड या चेक पर भरोसा नहीं कर रहे हैं। उन परिस्थितियों में जहां प्रदर्शन असाधारण रूप से महत्वपूर्ण नहीं है, यह बहुत सारे गंदे switch
बयानों या अन्य जांचों को बचाएगा !
संपादित करें
@ChaseMedallion को इंगित करने के लिए धन्यवाद कि मेरे मूल कार्यान्वयन ने नकारात्मक मूल्यों का समर्थन नहीं किया। यह उपलब्ध कराया गया है और परीक्षण किया गया है।
और इसे वापस करने के लिए परीक्षण:
[TestClass]
public class EnumExtensionsTests
{
[Flags]
enum WithFlags
{
First = 1,
Second = 2,
Third = 4,
Fourth = 8
}
enum WithoutFlags
{
First = 1,
Second = 22,
Third = 55,
Fourth = 13,
Fifth = 127
}
enum WithoutNumbers
{
First, // 1
Second, // 2
Third, // 3
Fourth // 4
}
enum WithoutFirstNumberAssigned
{
First = 7,
Second, // 8
Third, // 9
Fourth // 10
}
enum WithNagativeNumbers
{
First = -7,
Second = -8,
Third = -9,
Fourth = -10
}
[TestMethod]
public void IsValidEnumTests()
{
Assert.IsTrue(((WithFlags)(1 | 4)).IsValid());
Assert.IsTrue(((WithFlags)(1 | 4)).IsValid());
Assert.IsTrue(((WithFlags)(1 | 4 | 2)).IsValid());
Assert.IsTrue(((WithFlags)(2)).IsValid());
Assert.IsTrue(((WithFlags)(3)).IsValid());
Assert.IsTrue(((WithFlags)(1 + 2 + 4 + 8)).IsValid());
Assert.IsFalse(((WithFlags)(16)).IsValid());
Assert.IsFalse(((WithFlags)(17)).IsValid());
Assert.IsFalse(((WithFlags)(18)).IsValid());
Assert.IsFalse(((WithFlags)(0)).IsValid());
Assert.IsTrue(((WithoutFlags)1).IsValid());
Assert.IsTrue(((WithoutFlags)22).IsValid());
Assert.IsTrue(((WithoutFlags)(53 | 6)).IsValid()); // Will end up being Third
Assert.IsTrue(((WithoutFlags)(22 | 25 | 99)).IsValid()); // Will end up being Fifth
Assert.IsTrue(((WithoutFlags)55).IsValid());
Assert.IsTrue(((WithoutFlags)127).IsValid());
Assert.IsFalse(((WithoutFlags)48).IsValid());
Assert.IsFalse(((WithoutFlags)50).IsValid());
Assert.IsFalse(((WithoutFlags)(1 | 22)).IsValid());
Assert.IsFalse(((WithoutFlags)(9 | 27 | 4)).IsValid());
Assert.IsTrue(((WithoutNumbers)0).IsValid());
Assert.IsTrue(((WithoutNumbers)1).IsValid());
Assert.IsTrue(((WithoutNumbers)2).IsValid());
Assert.IsTrue(((WithoutNumbers)3).IsValid());
Assert.IsTrue(((WithoutNumbers)(1 | 2)).IsValid()); // Will end up being Third
Assert.IsTrue(((WithoutNumbers)(1 + 2)).IsValid()); // Will end up being Third
Assert.IsFalse(((WithoutNumbers)4).IsValid());
Assert.IsFalse(((WithoutNumbers)5).IsValid());
Assert.IsFalse(((WithoutNumbers)25).IsValid());
Assert.IsFalse(((WithoutNumbers)(1 + 2 + 3)).IsValid());
Assert.IsTrue(((WithoutFirstNumberAssigned)7).IsValid());
Assert.IsTrue(((WithoutFirstNumberAssigned)8).IsValid());
Assert.IsTrue(((WithoutFirstNumberAssigned)9).IsValid());
Assert.IsTrue(((WithoutFirstNumberAssigned)10).IsValid());
Assert.IsFalse(((WithoutFirstNumberAssigned)11).IsValid());
Assert.IsFalse(((WithoutFirstNumberAssigned)6).IsValid());
Assert.IsFalse(((WithoutFirstNumberAssigned)(7 | 9)).IsValid());
Assert.IsFalse(((WithoutFirstNumberAssigned)(8 + 10)).IsValid());
Assert.IsTrue(((WithNagativeNumbers)(-7)).IsValid());
Assert.IsTrue(((WithNagativeNumbers)(-8)).IsValid());
Assert.IsTrue(((WithNagativeNumbers)(-9)).IsValid());
Assert.IsTrue(((WithNagativeNumbers)(-10)).IsValid());
Assert.IsFalse(((WithNagativeNumbers)(-11)).IsValid());
Assert.IsFalse(((WithNagativeNumbers)(7)).IsValid());
Assert.IsFalse(((WithNagativeNumbers)(8)).IsValid());
}
}