web-dev-qa-db-ja.com

値を変更せずにEnum型のデフォルト値を選択する

C#では、値を変更せずに、Enum型を属性で装飾したり、デフォルト値を指定するために何か他のことを行うことは可能ですか?なんらかの理由で必要な数が石で設定されている可能性がありますが、それでもデフォルトを制御できると便利です。

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

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

enum(実際には、任意の値型)のデフォルトは0です(そのenumの有効な値ではない場合でも)。変更することはできません。

325
James Curran

列挙型のデフォルト値はゼロです。したがって、1つの列挙子をデフォルト値に設定する場合、その1つをゼロに設定し、他のすべての列挙子をゼロ以外に設定します(値がゼロの最初の列挙子は、複数の列挙子がある場合、その列挙のデフォルト値になります値ゼロ)。

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'

列挙子に明示的な値が必要ない場合は、最初の列挙子がデフォルトの列挙子になりたいことを確認してください。「デフォルトでは、最初の列挙子の値は0であり、連続する各列挙子の値は1.」 ( C#リファレンス

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

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

ゼロが適切なデフォルト値として機能しない場合は、コンポーネントモデルを使用して列挙型の回避策を定義できます。

[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);
        }
    }
}

そして、あなたは電話することができます:

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

注:ファイルの先頭に次の行を含める必要があります。

using System.ComponentModel;

これにより、列挙型の実際のC#言語のデフォルト値は変更されませんが、目的のデフォルト値を示す(および取得する)方法が提供されます。

35
David

列挙のデフォルトは、列挙がゼロに等しいものです。これは属性やその他の方法で変更できるとは思わない。

(MSDNは、「列挙型Eのデフォルト値は、式(E)0によって生成される値です。」)

17
Joe

できませんが、必要に応じて、いくつかのトリックを行うことができます。 :)

    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;
    }

この構造体を単純な列挙型として使用します。
ここで、デフォルトでp.a == Orientation.East(または任意の値)を作成できます
トリック自体を使用するには、intからコードで変換する必要があります。
実装があります:

        #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

役立つかもしれないもう1つの方法-ある種の「エイリアス」を使用する。例えば:

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

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

実際、enumのデフォルトは、enumの最初の要素であり、その値は0です。

たとえば、次のとおりです。

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) ...しかし、私は自分のプロジェクトでenumを使用することで重大な問題に直面し、以下のことを行うことで克服しました...私のニーズがクラスレベルにどのように関連していたか...

    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
    }

そして期待される結果を得る

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

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

ここで、DBから値が来ている場合はどうなりますか?...このシナリオでOk...以下の関数に値を渡すと、値をenumに変換します...関数がさまざまなシナリオを処理し、汎用です。 。そして、私はそれが非常に速いと信じています..... :)

    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

列挙型のデフォルト値は0です。

  • デフォルトでは、最初の列挙子の値は0であり、連続する各列挙子の値は1ずつ増加します。

  • 値型enumには、式(E)0によって生成される値があります。Eはenum識別子です。

C#enum here のドキュメントと、C#デフォルト値テーブル here のドキュメントを確認できます。

1
acoelhosantos

デフォルトの列挙型を最小値を持つ列挙型として定義する場合、これを使用できます。

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

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

firstEnum == Mine.

これは、列挙型の値がゼロであるとは想定していません。

1
Tal Segal

デフォルトは、定義の最初のものです。例えば:

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

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

これはHisを返します

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;
    }
}

プロパティをnullに設定すると、取得時にOrientations.Noneが返されます。プロパティ_orientationはデフォルトではnullです。

0
Faruk A Feres