आप C # में कई एनम मान कैसे पास करते हैं?


117

कभी-कभी दूसरों के C # कोड को पढ़ते समय मुझे एक ऐसी विधि दिखाई देती है जो एकल पैरामीटर में कई एनुम मानों को स्वीकार करेगी। मैंने हमेशा सोचा था कि यह साफ-सुथरा था, लेकिन इस पर कभी गौर नहीं किया।

खैर, अब मुझे लगता है कि मुझे इसकी आवश्यकता हो सकती है, लेकिन पता नहीं कैसे

  1. इसे स्वीकार करने के लिए विधि हस्ताक्षर सेट करें
  2. विधि में मूल्यों के साथ काम करते हैं
  3. एनम को परिभाषित करें

इस तरह की चीज को हासिल करना।


मेरी विशेष स्थिति में, मैं System.DayOfWeek का उपयोग करना चाहूंगा, जिसे इस प्रकार परिभाषित किया गया है:

[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{ 
    Sunday = 0,   
    Monday = 1,   
    Tuesday = 2,   
    Wednesday = 3,   
    Thursday = 4,   
    Friday = 5,    
    Saturday = 6
}

मैं अपने तरीके से DayOfWeek मानों में से एक या अधिक पास करने में सक्षम होना चाहता हूं। क्या मैं इस विशेष एनम का उपयोग कर पाऊंगा? मैं ऊपर सूचीबद्ध 3 चीजें कैसे करूं?


1
जैसा कि नीचे उल्लेख किया गया है, आप एक झंडे का उपयोग कर सकते हैं। आप C # enums की इन्स और आउटसाइज की जाँच करना चाहते हैं , जिसमें Flags enums के साथ काम करने की अधिक जानकारी है।
चेसमैडलियन

जवाबों:


181

जब आप एनम को परिभाषित करते हैं, तो इसे [फ्लैग्स] के साथ विशेषता दें, दो की शक्तियों के लिए मान सेट करें, और यह इस तरह से काम करेगा।

एक फ़ंक्शन में कई मानों को पारित करने के अलावा और कुछ नहीं बदलता है।

उदाहरण के लिए:

[Flags]
enum DaysOfWeek
{
   Sunday = 1,
   Monday = 2,
   Tuesday = 4,
   Wednesday = 8,
   Thursday = 16,
   Friday = 32,
   Saturday = 64
}

public void RunOnDays(DaysOfWeek days)
{
   bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday;

   if (isTuesdaySet)
      //...
   // Do your work here..
}

public void CallMethodWithTuesdayAndThursday()
{
    this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}

अधिक विवरण के लिए, Enumeration Types पर MSDN के दस्तावेज़ देखें ।


प्रश्न के अतिरिक्त परिवर्धन के जवाब में संपादित करें।

आप उस एनम का उपयोग नहीं कर पाएंगे, जब तक आप कुछ करना नहीं चाहते हैं जैसे कि इसे एक सरणी / संग्रह / पैराम्स सरणी के रूप में पास करें। यह आपको कई मान पास करेगा। झंडे के वाक्य-विन्यास में Enum को झंडे के रूप में निर्दिष्ट करने की आवश्यकता होती है (या भाषा को इस तरह से तैयार करने के लिए जिसे इसके डिज़ाइन नहीं किया गया है)।


9
मुझे लगता है कि यदि आप यह काम करना चाहते हैं, तो मूल्यों को दो की शक्तियों के रूप में परिभाषित किया जाना चाहिए, प्रत्येक मूल्य के लिए एक बिट। क्या होता है कि आप पैरामीटर के बिटवाइज़ या मानों में पास होते हैं, जिसे आप बिटवाइज़ और ऑपरेशंस का उपयोग करके देख सकते हैं। यदि आप मानों को परिभाषित करने का ध्यान नहीं रखते हैं, उदाहरण के लिए, 1,2,4,8 आदि, तो आपको समस्याएँ होंगी।
डेनिस ट्रोलर

1
केवल झंडे की विशेषता स्थापित करना अकेले काम नहीं करता है। मैंने बस कोशिश की।
रिचर्ड एंथनी हेन

1
आप सही हैं, और मैंने गलत सूचना को हटा दिया। रीड का कोड भी उसके लिए तय कर दिया।
मैथ्यू शारले

@monoxide: मैंने इसे उसी समय निर्धारित किया था - आपके संपादन को ओवरराइड करने के बारे में खेद।
रीड कोपसे

2
कोई बात नहीं ... मैं अभी भी उस तरह के झंडे मूल्यों के लिए हेक्स का उपयोग करना पसंद करता हूं, मुझे अधिक स्पष्ट लगता है, लेकिन प्रत्येक अपने स्वयं के लिए।
मैथ्यू शार्ले

78

मुझे लगता है कि Hasllag () का उपयोग करने के लिए अधिक सुरुचिपूर्ण समाधान है:

    [Flags]
    public enum DaysOfWeek
    {
        Sunday = 1,
        Monday = 2,
        Tuesday = 4,
        Wednesday = 8,
        Thursday = 16,
        Friday = 32,
        Saturday = 64
    }

    public void RunOnDays(DaysOfWeek days)
    {
        bool isTuesdaySet = days.HasFlag(DaysOfWeek.Tuesday);

        if (isTuesdaySet)
        {
            //...
        }
    }

    public void CallMethodWithTuesdayAndThursday()
    {
        RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
    }

एक और महत्वपूर्ण बात है, अगर आप इसे इस तरह करते हैं: यह बहुत अधिक लचीलापन जोड़ता है जब आपको अपने एनम को गतिशील रूप से भरने की आवश्यकता होती है। उदाहरण: यदि आप दिनों को परिभाषित करने के लिए चेकबॉक्स का उपयोग करते हैं, जिस पर आप अपना प्रोग्राम चलाना चाहते हैं, और आप इसे ऊपर दिए गए तरीके से पूरा करने का प्रयास करेंगे, तो कोड अपठनीय होगा। तो इसके बजाय आप इसे इस तरह से कर सकते हैं: DaysOfWeek days = new DaysOfWeek(); if (cbTuesday.Checked) days |= DaysOfWeek.Tuesday; if (cbWednesday.Checked) days |= DaysOfWeek.Wednesday;...
कोस्टल जूल

25

मैंने रीड का दूसरा जवाब दिया। हालाँकि, एनम बनाते समय, आपको प्रत्येक एनम सदस्य के लिए मान निर्दिष्ट करने होंगे ताकि यह एक प्रकार का बिट फ़ील्ड बना सके। उदाहरण के लिए:

[Flags]
public enum DaysOfWeek
{
    Sunday = 1,
    Monday = 2,
    Tuesday = 4,
    Wednesday = 8,
    Thursday = 16,
    Friday = 32,
    Saturday = 64,

    None = 0,
    All = Weekdays | Weekend,
    Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
    Weekend = Sunday | Saturday,
    // etc.
}

1
यदि आपको कभी भी किसी DaysOfWeek मूल्य का निरीक्षण करने की आवश्यकता होती है, तो यह आपकी मदद करेगा, उदाहरण के लिए यदि आप एक डेटाबेस में संग्रहीत एक को पढ़ रहे हैं। इसके अलावा, यह रविवार के बजाय सोमवार से शुरू होने वाले सप्ताह के कुछ शानदार दिनों के बाद से अन्य प्रोग्रामरों को बेहतर प्रलेखन प्रदान करता है।
जैकब

3
स्पष्टता और स्थिरता के लिए, मैं आपके "ऑल 'एनम को" संडे | सोमवार | मंगलवार | बुधवार | बुधवार | शुक्रवार | शनिवार "के रूप में लिखूंगा ... और' वीकेंड्स 'और' वीकेंड 'के लिए इसी तरह के अंकन का उपयोग करूंगा।
रॉबर्ट कार्टेनो

यह ठीक है अगर आप अपनी खुद की एनम बनाना चाहते हैं, लेकिन इस सवाल का जवाब देने के लिए आप मौजूदा DaysOfWeek एनम को बदल नहीं सकते
रॉबर्ट पॉलसन

2
"नहीं" चाहते हो सकता है ... तुम चाहिए। बिटवाइज तुलना की आवश्यकता है। मूल्यों को अनिर्दिष्ट छोड़ने से काम नहीं चलेगा।
रिचर्ड एंथनी हेन

11

अपनी विशेष स्थिति में, मैं System.DayOfWeek का उपयोग करना चाहूंगा

आप System.DayOfWeek को [Flags]एन्यूमरेशन के रूप में उपयोग नहीं कर सकते क्योंकि आपका इस पर कोई नियंत्रण नहीं है। यदि आप एक ऐसी विधि चाहते हैं जो एक से अधिक स्वीकार करती है DayOfWeekतो आपको paramsकीवर्ड का उपयोग करना होगा

void SetDays(params DayOfWeek[] daysToSet)
{
    if (daysToSet == null || !daysToSet.Any())
        throw new ArgumentNullException("daysToSet");

    foreach (DayOfWeek day in daysToSet)
    {
        // if( day == DayOfWeek.Monday ) etc ....
    }
}

SetDays( DayOfWeek.Monday, DayOfWeek.Sunday );

अन्यथा आप [Flags]कई अन्य उत्तरदाताओं द्वारा उल्लिखित के रूप में अपनी खुद की गणना बना सकते हैं और बिटवाइज़ तुलना का उपयोग कर सकते हैं ।


2
मुझे नहीं पता कि मैंने परम के बारे में क्यों नहीं सोचा। बिटम्स का उपयोग नहीं करने वाले एंथम का उपयोग करने के लिए यह बहुत उपयोगी होना चाहिए।
रॉनी ओवरबी

10
[Flags]
public enum DaysOfWeek
{
  Mon = 1,
  Tue = 2,
  Wed = 4,
  Thur = 8,
  Fri = 16,
  Sat = 32,
  Sun = 64
}

आपको संख्याओं को निर्दिष्ट करना होगा, और उन्हें इस तरह से बढ़ाना होगा क्योंकि यह बिटवाइज़ फैशन में मानों को संग्रहीत कर रहा है।

तो बस इस enum को लेने के लिए अपने तरीके को परिभाषित करें

public void DoSomething(DaysOfWeek day)
{
  ...
}

और यह कुछ ऐसा करने के लिए कहते हैं

DoSomething(DaysOfWeek.Mon | DaysOfWeek.Tue) // Both Monday and Tuesday

यह जांचने के लिए कि एनम के मूल्यों में से एक को शामिल किया गया था, जैसे बिटवाइज़ ऑपरेशन का उपयोग करके उन्हें जांचें

public void DoSomething(DaysOfWeek day)
{
  if ((day & DaysOfWeek.Mon) == DaysOfWeek.Mon) // Does a bitwise and then compares it to Mondays enum value
  {
    // Monday was passed in
  }
}

सवाल का जवाब नहीं देता। "मेरी विशेष स्थिति में, मैं System.DayOfWeek का उपयोग करना चाहूंगा"
रॉबर्ट पॉलसन

लेकिन यह वही है जिसकी मुझे तलाश है। तो वैसे भी धन्यवाद।
टिलिटो

3
[Flags]
    public enum DaysOfWeek{


        Sunday = 1 << 0,
        Monday = 1 << 1,
        Tuesday = 1 << 2,
        Wednesday = 1 << 3,
        Thursday = 1 << 4,
        Friday =  1 << 5,
        Saturday =  1 << 6
    }

इस प्रारूप में विधि को बुलाओ

MethodName (DaysOfWeek.Tuesday | DaysOfWeek.Thursday);

विकल्प पारित करने के लिए EnumToArray विधि लागू करें

private static void AddEntryToList(DaysOfWeek days, DaysOfWeek match, List<string> dayList, string entryText) {
            if ((days& match) != 0) {
                dayList.Add(entryText);
            }
        }

        internal static string[] EnumToArray(DaysOfWeek days) {
            List<string> verbList = new List<string>();

            AddEntryToList(days, HttpVerbs.Sunday, dayList, "Sunday");
            AddEntryToList(days, HttpVerbs.Monday , dayList, "Monday ");
            ...

            return dayList.ToArray();
        }

सवाल का जवाब नहीं देता। "मेरी विशेष स्थिति में, मैं System.DayOfWeek का उपयोग करना चाहूंगा"
रॉबर्ट पॉलसन

धन्यवाद, रॉबर्ट, लेकिन आपको वास्तव में हर उत्तर पर यह इंगित नहीं करना है।
रॉनी ओवरबी

@ रॉनी - शायद ही मेरी गलती है कि बहुत सारे डुप्लिकेट उत्तर हैं जो वास्तव में सवाल का जवाब नहीं देते थे।
रॉबर्ट पॉलसन

@ रॉनी - एनम टोस्ट्रिंग () और एनुम.पर्से () एक [फ्लैग] एन्यूमरेशन (जब तक आप कोर्स के एन्युमरेशन वर्जन से सावधान रहें) को आउटपुट / पार्स कर देंगे
रोबर्ट पॉलसन

@ रॉबर्ट - मुझे नहीं लगता कि कोई भी आपको दोषी ठहरा रहा है। सिर्फ वोटों की बात करते हैं।
रॉनी ओवरबी

3

[झंडे] विशेषता के साथ अपनी दुश्मनी को चिह्नित करें। यह भी सुनिश्चित करें कि आपके मामले में आपके सभी मूल्य परस्पर अनन्य हैं (दो मान एक दूसरे के बराबर नहीं जोड़ सकते हैं) जैसे 1,2,4,8,16,32,64

[Flags]
public enum DayOfWeek
{ 
Sunday = 1,   
Monday = 2,   
Tuesday = 4,   
Wednesday = 8,   
Thursday = 16,   
Friday = 32,    
Saturday = 64
}

जब आपके पास एक विधि होती है जो एक DayOfWeek enum को बिटवाइज या ऑपरेटर (!) का उपयोग करके एक साथ कई सदस्यों का उपयोग करने के लिए स्वीकार करता है। उदाहरण के लिए:

MyMethod(DayOfWeek.Sunday|DayOfWeek.Tuesday|DayOfWeek.Friday)

यह जाँचने के लिए कि क्या पैरामीटर में कोई विशिष्ट सदस्य है, जिस सदस्य के लिए आप जाँच कर रहे हैं, उसके साथ बिटवाइज़ और ऑपरेटर (&) का उपयोग करें ।

if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday)
Console.WriteLine("Contains Sunday");

सवाल का जवाब नहीं देता। "मेरी विशेष स्थिति में, मैं System.DayOfWeek का उपयोग करना चाहूंगा"
रॉबर्ट पॉलसन

2

रीड कोपसी सही है और अगर मैं कर सकता हूं, तो मैं मूल पोस्ट में जोड़ दूंगा, लेकिन मैं नहीं कर सकता इसलिए मुझे इसके बजाय जवाब देना होगा।

किसी भी पुरानी दुश्मनी पर सिर्फ [झंडे] का इस्तेमाल करना खतरनाक है। मेरा मानना ​​है कि आपको स्पष्ट रूप से झंडे का उपयोग करते समय मूल्यों में झड़पों से बचने के लिए, दो की शक्तियों को स्पष्ट रूप से बदलना होगा। FlagsAttribute और Enum के लिए दिशानिर्देश देखें ।


0

पोस्ट किए गए उत्तरों और इनकी मदद से:

  1. FlagsAttribute वर्ग ([झंडे] विशेषता का उपयोग करने और उपयोग न करने की तुलना में देखें)
  2. Enum झंडे विशेषता

मुझे लगता है कि मैं इसे बहुत अच्छी तरह से समझता हूं।

धन्यवाद।


-3

इस प्रकृति के कुछ को दिखाना चाहिए कि आप क्या देख रहे हैं:

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

public class SomeClass()
{
    public void SomeMethod(SomeName enumInput)
    {
        ...
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.