wake-up-neo.com

Auswählen des Standardwerts eines Aufzählungstyps, ohne dass Werte geändert werden müssen

Ist es in C # möglich, einen Enum-Typ mit einem Attribut zu dekorieren oder etwas anderes zu tun, um den Standardwert anzugeben, ohne die Werte ändern zu müssen? Die erforderlichen Zahlen könnten aus irgendeinem Grund in Stein gemeißelt sein, und es wäre praktisch, weiterhin die Kontrolle über die Standardwerte zu haben.

enum Orientation
{
    None = -1,
    North = 0,
    East = 1,
    South = 2,
    West = 3
}

Orientation o; // Is 'North' by default.
190
xyz

Der Standardwert für ein enum (in der Tat ein beliebiger Wertetyp) ist 0 - auch wenn dies kein gültiger Wert für dieses enum ist. Es kann nicht geändert werden.

325
James Curran

Der Standardwert jeder Aufzählung ist Null. Wenn Sie also einen Enumerator als Standardwert festlegen möchten, setzen Sie diesen auf Null und alle anderen Enumeratoren auf einen Wert ungleich Null (der erste Enumerator mit dem Wert Null ist der Standardwert für diese Enumeration, wenn mehrere Enumeratoren vorhanden sind mit dem Wert Null).

enum Orientation
{
    None = 0, //default value since it has the value '0'
    North = 1,
    East = 2,
    South = 3,
    West = 4
}

Orientation o; // initialized to 'None'

Wenn Ihre Enumeratoren keine expliziten Werte benötigen, stellen Sie einfach sicher, dass der erste Enumerator derjenige ist, den Sie als Standardenumerator verwenden möchten, da "Standardmäßig hat der erste Enumerator den Wert 0, und der Wert jedes nachfolgenden Enumerators wird um erhöht 1. " ( C # -Referenz )

enum Orientation
{
    None, //default value since it is the first enumerator
    North,
    East,
    South,
    West
}

Orientation o; // initialized to 'None'
62
user65199

Wenn Null nicht als der richtige Standardwert funktioniert, können Sie das Komponentenmodell verwenden, um eine Problemumgehung für die Aufzählung zu definieren:

[DefaultValue(None)]
public enum Orientation
{
     None = -1,
     North = 0,
     East = 1,
     South = 2,
     West = 3
 }

public static class Utilities
{
    public static TEnum GetDefaultValue<TEnum>() where TEnum : struct
    {
        Type t = typeof(TEnum);
        DefaultValueAttribute[] attributes = (DefaultValueAttribute[])t.GetCustomAttributes(typeof(DefaultValueAttribute), false);
        if (attributes != null &&
            attributes.Length > 0)
        {
            return (TEnum)attributes[0].Value;
        }
        else
        {
            return default(TEnum);
        }
    }
}

und dann können Sie anrufen:

Orientation o = Utilities.GetDefaultValue<Orientation>();
System.Diagnostics.Debug.Print(o.ToString());

Hinweis: Sie müssen die folgende Zeile am Anfang der Datei einfügen:

using System.ComponentModel;

Dies ändert nicht den tatsächlichen C # -Sprachenstandardwert der Aufzählung, bietet jedoch die Möglichkeit, den gewünschten Standardwert anzugeben (und abzurufen).

35
David

Die Standardeinstellung einer Aufzählung ist die Aufzählung gleich Null. Ich glaube nicht, dass dies durch Attribute oder andere Mittel geändert werden kann.

(MSDN sagt: "Der Standardwert einer Aufzählung E ist der Wert, der durch den Ausdruck (E) 0 erzeugt wird.")

17
Joe

Sie können nicht, aber wenn Sie wollen, können Sie einen Trick machen. :)

    public struct Orientation
    {
        ...
        public static Orientation None = -1;
        public static Orientation North = 0;
        public static Orientation East = 1;
        public static Orientation South = 2;
        public static Orientation West = 3;
    }

verwendung dieser Struktur als einfache Aufzählung.
Hier können Sie standardmäßig p.a == Orientation.East (oder einen beliebigen Wert) erstellen
Um den Trick selbst zu benutzen, müssen Sie von int per Code konvertieren.
dort die umsetzung:

        #region ConvertingToEnum
        private int val;
        static Dictionary<int, string> dict = null;

        public Orientation(int val)
        {
            this.val = val;
        }

        public static implicit operator Orientation(int value)
        {
            return new Orientation(value - 1);
        }

        public static bool operator ==(Orientation a, Orientation b)
        {
            return a.val == b.val;
        }

        public static bool operator !=(Orientation a, Orientation b)
        {
            return a.val != b.val;
        }

        public override string ToString()
        {
            if (dict == null)
                InitializeDict();
            if (dict.ContainsKey(val))
                return dict[val];
            return val.ToString();
        }

        private void InitializeDict()
        {
            dict = new Dictionary<int, string>();
            foreach (var fields in GetType().GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                dict.Add(((Orientation)fields.GetValue(null)).val, fields.Name);
            }
        } 
        #endregion
10
Avram

Ein weiterer Weg, der hilfreich sein könnte - eine Art "Alias" zu verwenden. Beispielsweise:

public enum Status
{
    New = 10,
    Old = 20,
    Actual = 30,

    // Use Status.Default to specify default status in your code. 
    Default = New 
}
8
Dmitry Pavlov

Tatsächlich ist der Standardwert von enum das erste Element in enum, dessen Wert 0 Ist.

Also zum Beispiel:

public enum Animals
{
    Cat,
    Dog,
    Pony = 0,
}
//its value will actually be Cat not Pony unless you assign a non zero value to Cat.
Animals animal;
6
Cian

The default value of enum is the enummember equal to 0 or the first element(if value is not specified) ... Aber ich habe bei der Verwendung von enum in meinen Projekten mit kritischen Problemen zu kämpfen gehabt und diese durch die folgenden Maßnahmen überwunden ... Wie auch immer mein Bedürfnis mit der Klassenstufe zusammenhängt ...

    class CDDtype
    {
        public int Id { get; set; }
        public DDType DDType { get; set; }

        public CDDtype()
        {
            DDType = DDType.None;
        }
    }    


    [DefaultValue(None)]
    public enum DDType
    {       
        None = -1,       
        ON = 0,       
        FC = 1,       
        NC = 2,       
        CC = 3
    }

und erwartetes Ergebnis bekommen

    CDDtype d1= new CDDtype();
    CDDtype d2 = new CDDtype { Id = 50 };

    Console.Write(d1.DDType);//None
    Console.Write(d2.DDType);//None

Was nun, wenn der Wert aus dem DB kommt? Ok in diesem Szenario ... Übergebe den Wert in die Funktion below und wandle den Wert in die Funktion enum ... below um Generika ... und glauben Sie mir, es ist sehr schnell ..... :)

    public static T ToEnum<T>(this object value)
    {
        //Checking value is null or DBNull
        if (!value.IsNull())
        {
            return (T)Enum.Parse(typeof(T), value.ToStringX());
        }

        //Returanable object
        object ValueToReturn = null;

        //First checking whether any 'DefaultValueAttribute' is present or not
        var DefaultAtt = (from a in typeof(T).CustomAttributes
                          where a.AttributeType == typeof(DefaultValueAttribute)
                          select a).FirstOrNull();

        //If DefaultAttributeValue is present
        if ((!DefaultAtt.IsNull()) && (DefaultAtt.ConstructorArguments.Count == 1))
        {
            ValueToReturn = DefaultAtt.ConstructorArguments[0].Value;
        }

        //If still no value found
        if (ValueToReturn.IsNull())
        {
            //Trying to get the very first property of that enum
            Array Values = Enum.GetValues(typeof(T));

            //getting very first member of this enum
            if (Values.Length > 0)
            {
                ValueToReturn = Values.GetValue(0);
            }
        }

        //If any result found
        if (!ValueToReturn.IsNull())
        {
            return (T)Enum.Parse(typeof(T), ValueToReturn.ToStringX());
        }

        return default(T);
    }
4
Moumit

Der Standardwert für einen Aufzählungstyp ist 0:

  • " Standardmäßig hat der erste Enumerator den Wert 0, und der Wert jedes nachfolgenden Enumerators wird um 1 erhöht. "

  • " Der Werttyp enum hat den Wert, der durch den Ausdruck (E) 0 erzeugt wird, wobei E der Enum-Bezeichner ist. "

Sie können die Dokumentation zu C # enum hier und die Dokumentation zur C # -Standardwertetabelle hier überprüfen.

1
acoelhosantos

Wenn Sie die Standardaufzählung als die Aufzählung mit dem kleinsten Wert definieren, können Sie dies verwenden:

public enum MyEnum { His = -1, Hers = -2, Mine = -4, Theirs = -3 }

var firstEnum = ((MyEnum[])Enum.GetValues(typeof(MyEnum)))[0];

firstEnum == Mine.

Dies setzt nicht voraus, dass die Aufzählung einen Nullwert hat.

1
Tal Segal

Der Standardwert ist der erste in der Definition. Beispielsweise:

public enum MyEnum{His,Hers,Mine,Theirs}

Enum.GetValues(typeOf(MyEnum)).GetValue(0);

Dies gibt His zurück

1
Tony Hopkinson
enum Orientations
{
    None, North, East, South, West
}
private Orientations? _orientation { get; set; }

public Orientations? Orientation
{
    get
    {
        return _orientation ?? Orientations.None;
    }
    set
    {
        _orientation = value;
    }
}

Wenn Sie die Eigenschaft auf null setzen, wird Orientations.None on get zurückgegeben. Die Eigenschaft _orientation ist standardmäßig null.

0
Faruk A Feres