मैंने कुछ समय पहले एक सेट एक्सटेंशन मेथड लिखा था जो कई तरह के Enumएस के लिए काम करता है । आप क्या हासिल करने की कोशिश कर रहे हैं और हैंडल के लिए विशेष रूप से काम करता है में से एक Enumके साथ FlagsAttributeके साथ ही Enumविभिन्न प्रकार के साथ अंतर्निहित है।
public static tEnum SetFlags<tEnum>(this Enum e, tEnum flags, bool set, bool typeCheck = true) where tEnum : IComparable
{
if (typeCheck)
{
if (e.GetType() != flags.GetType())
throw new ArgumentException("Argument is not the same type as this instance.", "flags");
}
var flagsUnderlyingType = Enum.GetUnderlyingType(typeof(tEnum));
var firstNum = Convert.ToUInt32(e);
var secondNum = Convert.ToUInt32(flags);
if (set)
firstNum |= secondNum;
else
firstNum &= ~secondNum;
var newValue = (tEnum)Convert.ChangeType(firstNum, flagsUnderlyingType);
if (!typeCheck)
{
var values = Enum.GetValues(typeof(tEnum));
var lastValue = (tEnum)values.GetValue(values.Length - 1);
if (newValue.CompareTo(lastValue) > 0)
return lastValue;
}
return newValue;
}
वहां से आप अन्य विशिष्ट एक्सटेंशन विधियों को जोड़ सकते हैं।
public static tEnum AddFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable
{
SetFlags(e, flags, true);
}
public static tEnum RemoveFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable
{
SetFlags(e, flags, false);
}
यह एक के प्रकार बदल जाएगा Enumजैसे आप करने की कोशिश कर रहे हैं।
public static tEnum ChangeType<tEnum>(this Enum e) where tEnum : IComparable
{
return SetFlags(e, default(tEnum), true, false);
}
हालांकि, चेतावनी दी जाती है कि आप इस पद्धति का उपयोग करके Enumकिसी भी और किसी भी व्यक्ति के बीच परिवर्तित कर सकते हैं Enum, यहां तक कि जिनके पास झंडे नहीं हैं। उदाहरण के लिए:
public enum Turtle
{
None = 0,
Pink,
Green,
Blue,
Black,
Yellow
}
[Flags]
public enum WriteAccess : short
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = 3
}
static void Main(string[] args)
{
WriteAccess access = WriteAccess.ReadWrite;
Turtle turtle = access.ChangeType<Turtle>();
}
चर turtleका मान होगा Turtle.Blue।
हालांकि, Enumइस पद्धति का उपयोग करके अपरिभाषित मूल्यों से सुरक्षा है । उदाहरण के लिए:
static void Main(string[] args)
{
Turtle turtle = Turtle.Yellow;
WriteAccess access = turtle.ChangeType<WriteAccess>();
}
इस मामले में , के बाद से accessसेट किया जाएगाWriteAccess.ReadWriteWriteAccess Enum 3 के अधिकतम मूल्य के ।
मिक्सिंग और इसके बिना उन लोगों के Enumसाथ मिश्रण का एक और दुष्प्रभाव FlagsAttributeयह है कि रूपांतरण की प्रक्रिया उनके मूल्यों के बीच 1 से 1 मैच नहीं होगी।
public enum Letters
{
None = 0,
A,
B,
C,
D,
E,
F,
G,
H
}
[Flags]
public enum Flavors
{
None = 0,
Cherry = 1,
Grape = 2,
Orange = 4,
Peach = 8
}
static void Main(string[] args)
{
Flavors flavors = Flavors.Peach;
Letters letters = flavors.ChangeType<Letters>();
}
इस मामले में, lettersके एक मूल्य होगा Letters.Hबजाय Letters.D, के बाद से के समर्थन मूल्य Flavors.Peach8. इसके अलावा है से एक रूपांतरण, Flavors.Cherry | Flavors.Grapeको Lettersप्राप्त होते हैं Letters.C, जो unintuitive लग सकता है।