क्या हम सी # में enums के अंतर्निहित रूपांतरण परिभाषित कर सकते हैं?

क्या सी # में enums के एक अंतर्निहित रूपांतरण को परिभाषित करना संभव है?

ऐसा कुछ जो इसे प्राप्त कर सकता है?

public enum MyEnum
{
    one = 1, two = 2
}

MyEnum number = MyEnum.one;
long i = number;

यदि नहीं, तो क्यों नहीं?

For further discussion and ideas on this, I followed up with how I currently handle this: Improving the C# enum

0
मैं भी यह करना चाहता हूँ। हमारे पास एक enum enum YesNo {Yes, No} है जो अंतर्निहित रूप से बूल में परिवर्तित हो सकता है।
जोड़ा लेखक Colonel Panic, स्रोत
यह नोट करते हुए कि यह अवधारणा संकलक प्रकार सुरक्षा जांच को अक्षम करती है। लंबी अवधि, एक स्पष्ट रूपांतरण शॉर्टेंड एक पिछला '~' की तरह बेहतर हो सकता है।
जोड़ा लेखक crokusek, स्रोत

10 उत्तर

आप शायद enum के लिए नहीं कर सकते हैं, लेकिन आप इसे एक विधि नहीं जोड़ सकते हैं)। एक एनम को इसमें परिवर्तित करने की अनुमति देने के लिए आप अपनी कक्षा में एक अंतर्निहित रूपांतरण जोड़ सकते हैं,

public class MyClass {

    public static implicit operator MyClass ( MyEnum input ) {
        //...
    }
}

MyClass m = MyEnum.One;

सवाल क्यों होगा?

आम तौर पर .Net किसी भी अंतर्निहित रूपांतरण से बचाता है (और आपको भी चाहिए) जहां डेटा खोया जा सकता है।

0
जोड़ा

आप रूपांतरणों को इंगित नहीं कर सकते (शून्य को छोड़कर), और आप अपनी खुद की इंस्टेंस विधियों को नहीं लिख सकते हैं - हालांकि, आप शायद अपनी खुद की एक्सटेंशन विधियां लिख सकते हैं:

public enum MyEnum { A, B, C }
public static class MyEnumExt
{
    public static int Value(this MyEnum foo) { return (int)foo; }
    static void Main()
    {
        MyEnum val = MyEnum.A;
        int i = val.Value();
    }
}

यह आपको बहुत कुछ नहीं देता है, हालांकि (केवल एक स्पष्ट कलाकार करने की तुलना में)।

One of the main times I've seen people want this is for doing [Flags] manipulation via generics - i.e. a bool IsFlagSet(T value, T flag); method. Unfortunately, C# 3.0 doesn't support operators on generics, but you can get around this using things like this, which make operators fully available with generics.

0
जोड़ा
हाँ, यह सी # 4 के लिए मेरी सबसे ज्यादा वांछित थी: stackoverflow.com/questions/138367/… के लिए सुविधा और stackoverflow.com/questions/7244
@ केथ - अच्छी नौकरी ने इसे बनाया, फिर ;- गतिशील/ऑपरेटर समर्थन ने इसे सीटीपी में नहीं बनाया, लेकिन मुझे गतिशील के साथ ऑपरेटरों के लिए दो दृष्टिकोणों की तुलना करने के लिए एक परीक्षण रिग तैयार करने के लिए रोल मिला है ( बनाम जेनेरिक/अभिव्यक्ति) जब यह वहां जाता है।
जोड़ा लेखक Marc Gravell, स्रोत
@ किथ - आप एक भंवर में ऑपरेटर कक्षा देना चाहते हैं; मुझे पूरा यकीन है कि यह आप जो चाहते हैं उससे अधिक करेंगे।
जोड़ा लेखक Marc Gravell, स्रोत

मैंने मार्क के उत्कृष्ट रिचएनम जेनेरिक बेसक्लास को अनुकूलित किया।

फिक्सिंग

  1. अपने पुस्तकालयों से लापता बिट्स के कारण कई संकलन समस्याएं (विशेष रूप से: संसाधन निर्भर प्रदर्शन नाम पूरी तरह से हटा नहीं दिए गए थे; वे अब हैं)
  2. प्रारंभिकता सही नहीं थी: यदि आपने पहली चीज स्थिर की थी तो बेस क्लास से वैल्यूज संपत्ति, आपको एनपीई मिल जाएगा। बेस क्लास को उत्सुकता से-पुनरावर्ती ( CRTP ) पर मजबूर करके इसे ठीक करें। चेकइनिलाइज्ड
  3. के दौरान बस समय पर TDerived के स्थिर निर्माण को मजबूर करें
  4. आखिर में एक स्थिर कन्स्ट्रक्टर में चेकइंस्टाईलाइज्ड लॉजिक को स्थानांतरित कर दिया गया (प्रत्येक बार जांचने के दंड से बचने के लिए, मल्टीथ्रेडेड प्रारंभिकरण पर दौड़ की स्थिति; शायद यह मेरी बुलेट 1 द्वारा हल की गई असंभवता थी।)

शानदार विचार + कार्यान्वयन के लिए चिह्नित करने के लिए कुडोस, यहां आप सभी के लिए है:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;

namespace NMatrix
{

    [DebuggerDisplay("{Value} ({Name})")]
    public abstract class RichEnum
                : IEquatable<tderived>,
                  IComparable<tderived>,
                  IComparable, IComparer<tderived>
        where TValue : struct, IComparable, IEquatable
        where TDerived : RichEnum
    {
        #region Backing Fields

        /// 
        /// The value of the enum item
        /// 
        public readonly TValue Value;

        /// 
        /// The public field name, determined from reflection
        /// 
        private string _name;

        /// 
        /// The DescriptionAttribute, if any, linked to the declaring field
        /// 
        private DescriptionAttribute _descriptionAttribute;

        /// 
        /// Reverse lookup to convert values back to local instances
        /// 
        private static readonly SortedList _values = new SortedList();

        #endregion

        #region Constructors

        protected RichEnum(TValue value)
        {
            this.Value = value;
            _values.Add(value, (TDerived)this);
        }

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return _name;
            }
        }

        public string Description
        {
            get
            {
                if (_descriptionAttribute != null)
                    return _descriptionAttribute.Description;

                return _name;
            }
        }

        #endregion

        #region Initialization

        static RichEnum()
        {
            var fields = typeof(TDerived)
                .GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public)
                .Where(t => t.FieldType == typeof(TDerived));

            foreach (var field in fields)
            {
                /*var dummy =*/ field.GetValue(null);//forces static initializer to run for TDerived

                TDerived instance = (TDerived)field.GetValue(null);
                instance._name = field.Name;
                                    instance._descriptionAttribute = field.GetCustomAttributes(true).OfType().FirstOrDefault();
            }
        }

        #endregion

        #region Conversion and Equality

        public static TDerived Convert(TValue value)
        {
            return _values[value];
        }

        public static bool TryConvert(TValue value, out TDerived result)
        {
            return _values.TryGetValue(value, out result);
        }

        public static implicit operator TValue(RichEnum value)
        {
            return value.Value;
        }

        public static implicit operator RichEnum(TValue value)
        {
            return _values[value];
        }

        public static implicit operator TDerived(RichEnum value)
        {
            return value;
        }

        public override string ToString()
        {
            return _name;
        }

        #endregion

        #region IEquatable<tderived> Members

        public override bool Equals(object obj)
        {
            if (obj != null)
            {
                if (obj is TValue)
                    return Value.Equals((TValue)obj);

                if (obj is TDerived)
                    return Value.Equals(((TDerived)obj).Value);
            }
            return false;
        }

        bool IEquatable<tderived>.Equals(TDerived other)
        {
            return Value.Equals(other.Value);
        }


        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        #endregion

        #region IComparable Members

        int IComparable<tderived>.CompareTo(TDerived other)
        {
            return Value.CompareTo(other.Value);
        }

        int IComparable.CompareTo(object obj)
        {
            if (obj != null)
            {
                if (obj is TValue)
                    return Value.CompareTo((TValue)obj);

                if (obj is TDerived)
                    return Value.CompareTo(((TDerived)obj).Value);
            }
            return -1;
        }

        int IComparer<tderived>.Compare(TDerived x, TDerived y)
        {
            return (x == null) ? -1 :
                   (y == null) ? 1 :
                    x.Value.CompareTo(y.Value);
        }

        #endregion

        public static IEnumerable<tderived> Values
        {
            get
            {
                return _values.Values;
            }
        }

        public static TDerived Parse(string name)
        {
            foreach (TDerived value in Values)
                if (0 == string.Compare(value.Name, name, true))
                    return value;

            return null;
        }
    }
}

मोनो पर उपयोग किए जाने वाले उपयोग का एक नमूना:

using System.ComponentModel;
using System;

namespace NMatrix
{

    public sealed class MyEnum : RichEnum
    {
        [Description("aap")]  public static readonly MyEnum my_aap   = new MyEnum(63000);
        [Description("noot")] public static readonly MyEnum my_noot  = new MyEnum(63001);
        [Description("mies")] public static readonly MyEnum my_mies  = new MyEnum(63002);

        private MyEnum(int value) : base (value) { } 
        public static implicit operator MyEnum(int value) { return Convert(value); }
    }

    public static class Program
    {
        public static void Main(string[] args)
        {
            foreach (var enumvalue in MyEnum.Values)
                Console.WriteLine("MyEnum {0}: {1} ({2})", (int) enumvalue, enumvalue, enumvalue.Description);
        }
    }


}

उत्पादन का उत्पादन

[mono] ~/custom/demo @ gmcs test.cs richenum.cs && ./test.exe 
MyEnum 63000: my_aap (aap)
MyEnum 63001: my_noot (noot)
MyEnum 63002: my_mies (mies)

1 mono 2.6.7 requiring an extra explicit cast that is not required when using mono 2.8.2...

0
जोड़ा
@kerem अच्छा बिंदु, मैंने इसे अपडेट किया है ( FirstOrDefault का उपयोग करके, यह मानने से बचने के लिए कि केवल एक ही विशेषता है)। ऐसी चीजों को मानना ​​है या नहीं, यह एक अच्छा विचार है (या एक खराब एक, उस मामले के लिए) निश्चित रूप से, संदर्भ पर निर्भर है
जोड़ा लेखक sehe, स्रोत
@agentnega उस अतिरिक्त के लिए धन्यवाद। यह किसी की मदद कर सकता है।
जोड़ा लेखक sehe, स्रोत
@BatteryBackupUnit इस उत्तर को संपादित करने के लिए स्वतंत्र महसूस करें। मैं बाद में इसे वापस पाने की कोशिश करूंगा
जोड़ा लेखक sehe, स्रोत
@agentnega, @ sehe इस बीच मैंने वर्कअराउंड पोस्ट किया है (जो मोनो और "सामान्य" .NET पर एक अलग उत्तर में काम करना चाहिए, देखें: stackoverflow.com/a/30395889/684096
जोड़ा लेखक BatteryBackupUnit, स्रोत
इसे प्यार करो, लेकिन मैं एक समस्या में भाग गया: विंडोज 7/.NET 4.5 पर यह लाइन <कोड> TDerived instance = (TDerived) फ़ील्ड। GetValue (शून्य); परिणाम instance में अशक्त । ऐसा लगता है कि मोनो रनटाइम में .NET एक की तुलना में प्रारंभिक प्रकार का एक अलग क्रम होना चाहिए जो इसे काम करने की अनुमति देता है। पेचीदा! मुझे इसके बजाय उस कोड को स्थैतिक विधि में ले जाना पड़ा और उसे सबक्लास में टाइप प्रारंभकर्ता से कॉल करना पड़ा।
जोड़ा लेखक agentnega, स्रोत
वर्णन विशेषता प्राप्त करने के लिए .Single() का उपयोग करना एक अच्छा विचार नहीं है। यदि कोई विशेषता नहीं है, सिंगल() एक अपवाद फेंकता है, सिंगलऑर्डफॉल्ट() नहीं करता है।
जोड़ा लेखक kerem, स्रोत

MS.net (गैर-मोनो) पर कोड चलाते समय मैंने sehe का जवाब के साथ एक समस्या के आसपास काम किया है। मेरे लिए विशेष रूप से समस्या .NET 4.5.1 पर हुई लेकिन अन्य संस्करण भी प्रभावित हुए।

समस्या

प्रतिबिंब द्वारा सार्वजनिक स्थैतिक TDervied MyEnumValue तक पहुंच ( FieldInfo.GetValue (null) के माध्यम से नहीं प्रारंभ फ़ील्ड प्रारंभ होता है।

कामकाज

Instead of assigning names to TDerived instances upon the static initializer of RichEnum this is done lazily on first access of TDerived.Name. The code:

public abstract class RichEnum : EquatableBase<tderived>
    where TValue : struct, IComparable, IEquatable
    where TDerived : RichEnum
{
   //Enforcing that the field Name (´SomeEnum.SomeEnumValue´) is the same as its 
   //instances ´SomeEnum.Name´ is done by the static initializer of this class.
   //Explanation of initialization sequence:
   //1. the static initializer of ´RichEnum´ reflects TDervied and 
   //   creates a list of all ´public static TDervied´ fields:
   //  ´EnumInstanceToNameMapping´
   //2. the static initializer of ´TDerive´d assigns values to these fields
   //3. The user is now able to access the values of a field.
   //   Upon first access of ´TDervied.Name´ we search the list 
   //   ´EnumInstanceToNameMapping´ (created at step 1) for the field that holds
   //   ´this´ instance of ´TDerived´.
   //   We then get the Name for ´this´ from the FieldInfo
    private static readonly IReadOnlyCollection 
                            EnumInstanceToNameMapping = 
        typeof(TDerived)
            .GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public)
            .Where(t => t.FieldType == typeof(TDerived))
            .Select(fieldInfo => new EnumInstanceReflectionInfo(fieldInfo))
            .ToList();

    private static readonly SortedList Values =
        new SortedList();

    public readonly TValue Value;

    private readonly Lazy _name;

    protected RichEnum(TValue value)
    {
        Value = value;

       //SortedList doesn't allow duplicates so we don't need to do
       //duplicate checking ourselves
        Values.Add(value, (TDerived)this);

        _name = new Lazy(
                   () => EnumInstanceToNameMapping
                         .First(x => ReferenceEquals(this, x.Instance))
                         .Name);
    }

    public string Name
    {
        get { return _name.Value; }
    }

    public static implicit operator TValue(RichEnum richEnum)
    {
        return richEnum.Value;
    }

    public static TDerived Convert(TValue value)
    {
        return Values[value];
    }

    protected override bool Equals(TDerived other)
    {
        return Value.Equals(other.Value);
    }

    protected override int ComputeHashCode()
    {
        return Value.GetHashCode();
    }

    private class EnumInstanceReflectionInfo
    {
        private readonly FieldInfo _field;
        private readonly Lazy<tderived> _instance;

        public EnumInstanceReflectionInfo(FieldInfo field)
        {
            _field = field;
            _instance = new Lazy<tderived>(() => (TDerived)field.GetValue(null));
        }

        public TDerived Instance
        {
            get { return _instance.Value; }
        }

        public string Name { get { return _field.Name; } }
    }
}

which - in my case - is based upon EquatableBase:

public abstract class EquatableBase
    where T : class 
{
    public override bool Equals(object obj)
    {
        if (this == obj)
        {
            return true;
        }

        T other = obj as T;
        if (other == null)
        {
            return false;
        }

        return Equals(other);
    }

    protected abstract bool Equals(T other);

    public override int GetHashCode()
    {
        unchecked
        {
            return ComputeHashCode();
        }
    }

    protected abstract int ComputeHashCode();
}

ध्यान दें

उपर्युक्त कोड मार्क के मूल उत्तर की सभी सुविधाओं को शामिल नहीं करता है!

धन्यवाद

धन्यवाद to Mark for providing his RichEnum implementation and धन्यवाद to sehe for providing some improvements!

0
जोड़ा

यदि आप लंबे समय तक enum के आधार को परिभाषित करते हैं तो आप स्पष्ट रूपांतरण कर सकते हैं। मुझे नहीं पता कि आप निहित रूपांतरणों का उपयोग कर सकते हैं क्योंकि एनम्स पर उन तरीकों को परिभाषित नहीं किया जा सकता है।

public enum MyEnum : long
{
    one = 1,
    two = 2,
}

MyEnum number = MyEnum.one;
long i = (long)number;

साथ ही, इस बात से अवगत रहें कि एक अनियमित गणना 0 मान, या पहली वस्तु के लिए डिफ़ॉल्ट होगी - इसलिए ऊपर की स्थिति में शून्य = 0 को परिभाषित करने के लिए शायद सबसे अच्छा होगा।

0
जोड़ा
डिफ़ॉल्ट रूप से इट्स, तो आप किसी भी पूर्ण-संख्यात्मक प्रकार (बाइट, लघु, int, लंबा) बना सकते हैं
जोड़ा लेखक Keith, स्रोत
मैंने सोचा कि सभी enums जहां डिफ़ॉल्ट रूप से लंबे समय तक? इसलिए लंबे समय तक स्पष्ट रूपांतरण पहले से मौजूद है?
जोड़ा लेखक Adam Naylor, स्रोत
आपको यहां : लंबा की आवश्यकता नहीं है; स्पष्ट रूपांतरण इसके बिना ठीक काम करेगा। एकमात्र कानूनी निहित रूपांतरण शून्य है।
जोड़ा लेखक Marc Gravell, स्रोत
नहीं; डिफ़ॉल्ट enum Int32 है
जोड़ा लेखक Marc Gravell, स्रोत
देखें: enum foo {ए, बी, सी} कंसोल। राइटलाइन (Enum.GetUnderlyingType (typeof (Foo)));
जोड़ा लेखक Marc Gravell, स्रोत
सवाल पहले से ही तात्पर्य है कि स्पष्ट जानवरों को समझा जाता है, सवाल यह पूछने के बराबर है कि "मैं स्पष्ट रूप से कास्टिंग से कैसे बचूं?", जिसके लिए यह पोस्ट लागू नहीं होता है।
जोड़ा लेखक Kit10, स्रोत
इसे उत्तर के रूप में क्यों चिह्नित किया गया है और इसमें बहुत अधिक अंक हैं? यह ओपी सवाल के लिए प्रासंगिक नहीं है !!! वह लागू रूपांतरण के बारे में बात कर रहा है ... जोड़ा मूल्य शून्य है।
जोड़ा लेखक Mehdi LAMRANI, स्रोत

आप enum प्रकारों पर निहित रूपांतरण घोषित नहीं कर सकते हैं, क्योंकि वे विधियों को परिभाषित नहीं कर सकते हैं। सी # implicit कीवर्ड एक विधि में संकलित करता है 'op_' के साथ, और यह इस मामले में काम नहीं करेगा।

0
जोड़ा

एनम प्रकारों के लिए निहित रूपांतरणों को पेश करने से प्रकार की सुरक्षा टूट जाएगी, इसलिए मैं ऐसा करने की अनुशंसा नहीं करता। आप ऐसा क्यों करना चाहते हो? मैंने देखा है कि इसके लिए एकमात्र उपयोग का मामला यह है कि जब आप enum मानों को एक पूर्व-परिभाषित लेआउट के साथ संरचना में रखना चाहते हैं। लेकिन फिर भी, आप संरचना में enum प्रकार का उपयोग कर सकते हैं और बस मार्शलर को बताओ कि उसे इसके साथ क्या करना चाहिए।

0
जोड़ा
मेरे पास enums के निहित रूपांतरण के लिए उपयोग है। उसी साइट संग्रह की एकाधिक साइटों में LINP से SharePoint कक्षाएं उत्पन्न करने के लिए SPMetal का उपयोग करना। मेरी कुछ सूचियां एक सबसाइट में हैं, अन्य एक अलग सबसाइट में हैं। एसपीएमटल कोड कैसे उत्पन्न करता है, इस कारण संग्रह की कई सूचियों में उपयोग किए जाने वाले साइट कॉलम को कई नामस्थानों में परिभाषित किया जा सकता है। हालांकि, मुझे किसी अन्य नामस्थान में एक ही नाम पर एक फ़ील्ड में पसंद फ़ील्ड एनम के बीच कनवर्ट करने की आवश्यकता है। लागू रूपांतरण बहुत उपयोगी होगा।
जोड़ा लेखक Zarepheth, स्रोत

एक समाधान है निम्नलिखित को धयान मे रखते हुए:

public sealed class AccountStatus
{
    public static readonly AccountStatus Open = new AccountStatus(1);
    public static readonly AccountStatus Closed = new AccountStatus(2);

    public static readonly SortedList Values = new SortedList();
    private readonly byte Value;

    private AccountStatus(byte value)
    {
        this.Value = value;
        Values.Add(value, this);
    }


    public static implicit operator AccountStatus(byte value)
    {
        return Values[byte];
    }

    public static implicit operator byte(AccountStatus value)
    {
        return value.Value;
    }
}

उपरोक्त निहित रूपांतरण प्रदान करता है:

        AccountStatus openedAccount = 1;           //Works
        byte openedValue = AccountStatus.Open;     //Works

This is a fair bit more work than declaring a normal enum (though you can refactor some of the above into a common generic base class). You can go even further by having the base class implement IComparable & IEquatable, as well as adding methods to return the value of DescriptionAttributes, declared names, etc, etc.

I wrote a base class (RichEnum<>) to handle most fo the grunt work, which eases the above declaration of enums down to:

public sealed class AccountStatus : RichEnum
{
    public static readonly AccountStatus Open = new AccountStatus(1);
    public static readonly AccountStatus Closed = new AccountStatus(2);

    private AccountStatus(byte value) : base (value)
    {
    }

    public static implicit operator AccountStatus(byte value)
    {
        return Convert(value);
    }
}

बेस क्लास (RichEnum) नीचे सूचीबद्ध है।

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;

namespace Ethica
{
    using Reflection;
    using Text;

    [DebuggerDisplay("{Value} ({Name})")]
    public abstract class RichEnum
                : IEquatable<tderived>,
                  IComparable<tderived>,
                  IComparable, IComparer<tderived>
        where TValue : struct , IComparable, IEquatable
        where TDerived : RichEnum
    {
        #region Backing Fields

        /// 
        /// The value of the enum item
        /// 
        public readonly TValue Value;

        /// 
        /// The public field name, determined from reflection
        /// 
        private string _name;

        /// 
        /// The DescriptionAttribute, if any, linked to the declaring field
        /// 
        private DescriptionAttribute _descriptionAttribute;

        /// 
        /// Reverse lookup to convert values back to local instances
        /// 
        private static SortedList _values;

        private static bool _isInitialized;


        #endregion

        #region Constructors

        protected RichEnum(TValue value)
        {
            if (_values == null)
                _values = new SortedList();
            this.Value = value;
            _values.Add(value, (TDerived)this);
        }

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                CheckInitialized();
                return _name;
            }
        }

        public string Description
        {
            get
            {
                CheckInitialized();

                if (_descriptionAttribute != null)
                    return _descriptionAttribute.Description;

                return _name;
            }
        }

        #endregion

        #region Initialization

        private static void CheckInitialized()
        {
            if (!_isInitialized)
            {
                ResourceManager _resources = new ResourceManager(typeof(TDerived).Name, typeof(TDerived).Assembly);

                var fields = typeof(TDerived)
                                .GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public)
                                .Where(t => t.FieldType == typeof(TDerived));

                foreach (var field in fields)
                {

                    TDerived instance = (TDerived)field.GetValue(null);
                    instance._name = field.Name;
                    instance._descriptionAttribute = field.GetAttribute();

                    var displayName = field.Name.ToPhrase();
                }
                _isInitialized = true;
            }
        }

        #endregion

        #region Conversion and Equality

        public static TDerived Convert(TValue value)
        {
            return _values[value];
        }

        public static bool TryConvert(TValue value, out TDerived result)
        {
            return _values.TryGetValue(value, out result);
        }

        public static implicit operator TValue(RichEnum value)
        {
            return value.Value;
        }

        public static implicit operator RichEnum(TValue value)
        {
            return _values[value];
        }

        public static implicit operator TDerived(RichEnum value)
        {
            return value;
        }

        public override string ToString()
        {
            return _name;
        }

        #endregion

        #region IEquatable<tderived> Members

        public override bool Equals(object obj)
        {
            if (obj != null)
            {
                if (obj is TValue)
                    return Value.Equals((TValue)obj);

                if (obj is TDerived)
                    return Value.Equals(((TDerived)obj).Value);
            }
            return false;
        }

        bool IEquatable<tderived>.Equals(TDerived other)
        {
            return Value.Equals(other.Value);
        }


        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        #endregion

        #region IComparable Members

        int IComparable<tderived>.CompareTo(TDerived other)
        {
            return Value.CompareTo(other.Value);
        }

        int IComparable.CompareTo(object obj)
        {
            if (obj != null)
            {
                if (obj is TValue)
                    return Value.CompareTo((TValue)obj);

                if (obj is TDerived)
                    return Value.CompareTo(((TDerived)obj).Value);
            }
            return -1;
        }

        int IComparer<tderived>.Compare(TDerived x, TDerived y)
        {
            return (x == null) ? -1 :
                   (y == null) ? 1 :
                    x.Value.CompareTo(y.Value);
        }

        #endregion

        public static IEnumerable<tderived> Values
        {
            get
            {
                return _values.Values;
            }
        }

        public static TDerived Parse(string name)
        {
            foreach (TDerived value in _values.Values)
                if (0 == string.Compare(value.Name, name, true) || 0 == string.Compare(value.DisplayName, name, true))
                    return value;

            return null;
        }
    }
}
0
जोड़ा
यह समाधान व्यायाम के रूप में 'सही' हो सकता है, या किसी के प्रोग्रामिंग कौशल का परीक्षण कर सकता है, लेकिन, वास्तविक जीवन में ऐसा न करें। न केवल यह अधिक है, यह अनुत्पादक, अस्पष्ट और नरक के रूप में बदसूरत है। आपको इसके लिए सिर्फ एक enum का उपयोग करने की आवश्यकता नहीं है। आप या तो एक स्पष्ट कलाकार डालते हैं या केवल स्थिर कक्षा को स्थिरांक के साथ लिखते हैं।
जोड़ा लेखक Trap, स्रोत
आपके पहले उदाहरण (गैर-बेस क्लास दृष्टिकोण) SortedList को पहले कोड (कोड में ऊपर) से पहले परिभाषित करने की आवश्यकता है AccountStatus उदाहरण, अन्यथा कन्स्ट्रक्टर रनटाइम के दौरान शिकायत करेगा कि सॉर्टेडलिस्ट शून्य है
जोड़ा लेखक musefan, स्रोत
एक परियोजना में मैं काम करता हूं हमारे पास मेटाडेटा के साथ enums है। यह ऐसे डेटाबेस में प्रविष्टियों से मेल खाता है जो गतिशील रूप से परिवर्तित नहीं होते हैं और इस प्रकार स्थिर होते हैं। जैसे enum में एक क्षेत्र एक संबद्ध आदेश है। हम विस्तार विधियों का उपयोग करके कोड में इनका उपयोग करते हैं। जैसे MyEnum.SomeValue.SequenceOrder() । परिवर्तनीय 'मेटाडाटा' वाले enums के लिए एक nedd मुझे एक डिजाइन दोष की तरह लगता है।
जोड़ा लेखक Mike de Klerk, स्रोत
@IanGoldby हाँ आप इसे स्विच स्टेटमेंट में इस्तेमाल कर सकते हैं। एक स्थाई अंतर्निहित ऑपरेटर को परिभाषित करें जो एक पूर्णांक में परिवर्तित हो जाता है और एक वर्ग उदाहरण स्विच (उदाहरण) तरीके से उपयोग किया जा सकता है। लेकिन फिर, आप इसे स्विच स्टेटमेंट में लेबल्स के लिए उपयोग नहीं कर सकते क्योंकि उन्हें समय संकलन संकलित करना होगा।
जोड़ा लेखक Mike de Klerk, स्रोत
मैंने इस बेसक्लास संकलन को बनाया है। यदि आप परिवर्तनों में संपादित करते हैं तो क्या आपको बुरा लगता है?
जोड़ा लेखक sehe, स्रोत
उत्तम सामग्री। शर्म की बात मैं केवल इस मणि के लिए एक बार ऊपर उठ सकता हूं
जोड़ा लेखक sehe, स्रोत
एक बड़ी समस्या यह है कि आप स्विच स्टेटमेंट में उन स्थिर रीडोनली स्थिरांक का उपयोग नहीं कर सकते हैं।
जोड़ा लेखक Ian Goldby, स्रोत
@MikedeKlerk मुझे और अधिक स्पष्ट होना चाहिए था - जैसा कि आप उल्लेख करते हैं कि लेबल को संकलन समय संकलन करना है, यही कारण है कि मैंने कहा कि आप इसे स्विच स्टेटमेंट में उपयोग नहीं कर सकते हैं। यदि आप AccountStatus.Closed के बजाय एक शाब्दिक 2 के लेबल का उपयोग करते हैं तो बिंदु आप encapsulation तोड़ते हैं। हां, आप स्विच लेबल में उपयोग करने के लिए स्थिरांक परिभाषित कर सकते हैं और AccountStatus की अपनी परिभाषा में इन समान स्थिरांक का उपयोग कर सकते हैं, लेकिन मुझे लगता है कि यह मूल लक्ष्य और AccountStatus ।
जोड़ा लेखक Ian Goldby, स्रोत
क्या यह मूल रूप से जावा एनम को फिर से लागू नहीं किया गया है?
जोड़ा लेखक Agent_L, स्रोत
ऐसे कुछ स्थान हैं जहां आप स्थिर रीडोनली सदस्यों का उपयोग नहीं कर सकते हैं, लेकिन केवल const फ़ील्ड्स का उपयोग नहीं कर सकते हैं। जैसे विशेषता ctor पैरामीटर, और स्विच कथन भी इयान ने कहा।
जोड़ा लेखक Gabor, स्रोत
पोस्ट में थोड़ी सी ऑफगार्ड त्रुटि को ठीक किया गया :-) यह सार्वजनिक स्थिर अंतर्निहित ऑपरेटर खातास्टैटस (बाइट मान) {वापसी कनवर्ट (मान) है; } कनवर्ट (बाइट) वापस नहीं;
जोड़ा लेखक Mehdi LAMRANI, स्रोत
आप दोस्त रॉक! : ओ) थानएक्स
जोड़ा लेखक Mehdi LAMRANI, स्रोत
मैंने सोचा कि आप इस() को कन्स्ट्रक्टर में कैप्चर नहीं कर सके ... मेरा मानना ​​है कि इसे एक प्रकार प्रारंभकर्ता त्रुटि फेंकनी चाहिए, नहीं?
जोड़ा लेखक ElfsЯUs, स्रोत
struct PseudoEnum
{
    public const int 
              INPT = 0,
              CTXT = 1,
              OUTP = 2;
};

// ...

var arr = new String[3];

arr[PseudoEnum.CTXT] = "can";
arr[PseudoEnum.INPT] = "use";
arr[PseudoEnum.CTXT] = "as";
arr[PseudoEnum.CTXT] = "array";
arr[PseudoEnum.OUTP] = "index";
0
जोड़ा
यह मेरी राय में सबसे अच्छा है
जोड़ा लेखक Fred Mauroy, स्रोत

मुझे यहां से भी आसान समाधान मिला है https://codereview.stackexchange.com/questions/ 7566/enum-vs-int-wrapper-struct मैंने उस लिंक से नीचे दिए गए कोड को चिपकाया है, अगर यह भविष्य में काम नहीं करता है।

struct Day
{
    readonly int day;

    public static readonly Day Monday = 0;
    public static readonly Day Tuesday = 1;
    public static readonly Day Wednesday = 2;
    public static readonly Day Thursday = 3;
    public static readonly Day Friday = 4;
    public static readonly Day Saturday = 5;
    public static readonly Day Sunday = 6;

    private Day(int day)
    {
        this.day = day;
    }

    public static implicit operator int(Day value)
    {
        return value.day;
    }

    public static implicit operator Day(int value)
    {
        return new Day(value);
    }
}
0
जोड़ा