C# में int को enum में बदलना: यह कोड क्यों तोड़ता है और सही तरीके से कैसे ठीक करें
\n\nहर C# डेवलपर, यहाँ तक कि कुछ महीनों के अनुभव वाला भी, देर-सबेर इस सवाल का सामना करता है: «How do I cast int to enum in C#?»। Stack Overflow पर इस क्वेरी ने सैकड़ों हज़ारों व्यूज़ प्राप्त किए हैं — और यह सही भी है। लगता है, इसमें मुश्किल क्या है? (MyEnum)myInt लिखा — और हो गया। लेकिन शैतान, हमेशा की तरह, विवरणों में है। int को enum में गलत तरीके से बदलने से अपवाद, मुश्किल से पकड़ में आने वाले बग और यहाँ तक कि production सर्वर का क्रैश भी हो सकता है।
इस लेख में हम int को enum में कास्ट करने की शीर्ष 5 गलतियों पर चर्चा करेंगे, C# में काम करने वाले उदाहरण दिखाएँगे और सुरक्षित रूपांतरण के लिए एक स्पष्ट एल्गोरिदम देंगे। यदि आप C# में लिखते हैं और एनुम का उपयोग करते हैं, तो यह जानकारी आपके डीबगिंग के घंटे बचाएगी।
\n\nगलती नंबर 1: बिना जाँच के भोला रूपांतरण — «क्या होगा अगर संख्या अमान्य है?»
\n\nसबसे आम तरीका, जो शुरुआती लोग इंटरनेट पर पाते हैं, वह है सीधा कास्ट:
\n\nenum Status\n{\n Active = 1,\n Inactive = 2,\n Pending = 3\n}\n\nint input = 5; // उपयोगकर्ता ने कुछ गलत भेजा\nStatus status = (Status)input; // कोई त्रुटि नहीं, लेकिन status == (Status)5\nConsole.WriteLine(status); // आउटपुट: 5 — बेकार मान!\n\n\nकोड बिना किसी अपवाद के कंपाइल और एक्सीक्यूट हो जाएगा। लेकिन वेरिएबल status में अब मान 5 है, जो enum Status में मौजूद नहीं है। C# में, एनुम मूल रूप से नामों वाले पूर्णांक हैं। कंपाइलर यह जाँच नहीं करता कि मान स्थिरांकों के सेट से संबंधित है या नहीं। यह एक क्लासिक जाल है: int को enum में बदलना तकनीकी रूप से काम करता है, लेकिन तार्किक रूप से यह एक बग है।
कैसे बचें: कास्ट करने से पहले हमेशा Enum.IsDefined() मेथड का उपयोग करें।
if (Enum.IsDefined(typeof(Status), input))\n{\n Status status = (Status)input;\n}\nelse\n{\n // त्रुटि प्रबंधन: लॉगिंग, डिफ़ॉल्ट मान या अपवाद\n Console.WriteLine($"Status के लिए अमान्य मान {input}");\n}\n\n\nयाद रखें: बार-बार कॉल करने पर Enum.IsDefined() धीमा काम करता है, लेकिन एकल संचालन के लिए यह एक आदर्श रक्षक है।
गलती नंबर 2: फ़्लैग एनुम ([Flags]) को अनदेखा करना
\n\nजब आप [Flags] एट्रीब्यूट से चिह्नित एनुम के साथ काम करते हैं, तो जाँच का तर्क बदल जाता है। Enum.IsDefined() फ़्लैग के संयोजनों के लिए false लौटाएगा, भले ही वे सही हों।
[Flags]\nenum Permissions\n{\n None = 0,\n Read = 1,\n Write = 2,\n Execute = 4\n}\n\nint input = 3; // Read + Write\nif (Enum.IsDefined(typeof(Permissions), input))\n{\n // यह निष्पादित नहीं होगा! 3 कोई अलग स्थिरांक नहीं है\n}\n\n\nफ़्लैग के लिए, एक अलग जाँच का उपयोग करें: क्या संख्या के सभी बिट परिभाषित मानों के अनुरूप हैं।
\n\nbool IsValidFlags<T>(int value) where T : Enum\n{\n int allValues = 0;\n foreach (var v in Enum.GetValues<T>())\n {\n allValues |= Convert.ToInt32(v);\n }\n return (value & ~allValues) == 0;\n}\n\nif (IsValidFlags<Permissions>(input))\n{\n Permissions perms = (Permissions)input; // सुरक्षित\n}\n\n\nया, अगर फ़्लैग कम हैं, तो प्रत्येक अलग फ़्लैग के लिए बिल्ट-इन Enum.IsDefined() जाँच का उपयोग करें।
गलती नंबर 3: ऋणात्मक संख्याओं और ओवरफ़्लो की अनदेखी
\n\nC# में Enum डिफ़ॉल्ट रूप से int पर आधारित होता है, लेकिन byte, short, long आदि भी हो सकता है। यदि आप int को enum में बदल रहे हैं, और बेस टाइप byte है, तो आपको ओवरफ़्लो पर अपवाद मिल सकता है, या इससे भी बुरा, मान का चुपचाप विरूपण हो सकता है।
enum SmallEnum : byte\n{\n A = 0,\n B = 255\n}\n\nint bigValue = 300;\nSmallEnum se = (SmallEnum)bigValue; // कंपाइलेशन त्रुटि? नहीं!\n// लेकिन मान काट दिया जाएगा: se == (SmallEnum)44 (300 % 256)\n