मैंने कुछ समय पहले एक सेट एक्सटेंशन मेथड लिखा था जो कई तरह के 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.ReadWrite
WriteAccess
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.Peach
8. इसके अलावा है से एक रूपांतरण, Flavors.Cherry | Flavors.Grape
को Letters
प्राप्त होते हैं Letters.C
, जो unintuitive लग सकता है।