选择Enum类型的默认值而不必更改值

时间:2009-02-09 20:59:20

标签: c# .net enums

在C#中,是否可以使用属性修饰Enum类型或执行其他操作来指定默认值应该是什么,而不更改值?无论出于何种原因,所需的数字可能都是一成不变的,并且仍可以控制默认值。

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

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

14 个答案:

答案 0 :(得分:313)

enum(实际上是任何值类型)的默认值为0 - 即使它不是enum的有效值。它无法改变。

答案 1 :(得分:61)

任何枚举的默认值为零。因此,如果要将一个枚举器设置为默认值,则将其设置为零,将所有其他枚举器设置为非零(如果有多个枚举器,则第一个枚举值为零的第一个枚举器将是该枚举的默认值值为零。)

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# reference

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

Orientation o; // initialized to 'None'

答案 2 :(得分:33)

如果零不能作为正确的默认值,您可以使用组件模型来定义枚举的变通方法:

[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#语言默认值,但会提供一种指示(并获取)所需默认值的方法。

答案 3 :(得分:17)

枚举的默认值是枚举等于零。我不相信这可以通过属性或其他方式改变。

(MSDN说:“枚举E的默认值是表达式(E)0产生的值。”)

答案 4 :(得分:10)

你不能,但如果你愿意,你可以做一些技巧。 :)

    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

答案 5 :(得分:8)

另一种可能有用的方法 - 使用某种“别名”。 例如:

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

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

答案 6 :(得分:6)

实际上,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;

答案 7 :(得分:4)

The default value of enum is the enummember equal to 0 or the first element(if value is not specified) ...但是我在项目中使用枚举遇到了严重的问题,并通过以下方式做了一些事情......我的需求如何与班级相关......

    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 ......如果在这种情况下好了...在下面的函数中传递值,它会将值转换为枚举...在函数下面处理各种场景并且它是通用的......并且相信我很快.....:)

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

答案 8 :(得分:1)

默认值是定义中的第一个。例如:

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

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

这将返回His

答案 9 :(得分:1)

枚举类型的默认值为0:

  • &#34; 默认情况下,第一个枚举数的值为0,值为 每个连续的枚举器增加1。&#34;

  • &#34; 值类型枚举具有表达式(E)0生成的值,其中E是枚举 。标识符&#34;

您可以查看C#enum here的文档以及C#默认值表here的文档。

答案 10 :(得分:1)

如果将默认枚举定义为具有最小值的枚举,则可以使用:

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

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

firstEnum == Mine.

这并不假设枚举值为零。

答案 11 :(得分:0)

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.get上的任何内容。 _orientation属性默认为空。

答案 12 :(得分:0)

在这种情况下不要依赖枚举值。将 None 设为 0 作为默认值。

// Remove all the values from the enum
enum Orientation
{
    None, // = 0 Putting None as the first enum value will make it the default
    North, // = 1
    East, // = 2
    South, // = 3
    West // = 4
}

然后使用一种方法来获取Magic Number。您可以引入一个 Extension Method 并像这样使用它:

// Extension Methods are added by adding a using to the namespace
using ProjectName.Extensions;

Orientation.North.ToMagicNumber();

这是代码:

namespace ProjectName.Extensions
{
    public static class OrientationExtensions 
    {
        public static int ToMagicNumber(this Orientation orientation) => oritentation switch
        {
            case None  => -1,
            case North => 0,
            case East  => 1,
            case South => 2,
            case West  => 3,
            _          => throw new ArgumentOutOfRangeException(nameof(orientation), $"Not expected orientation value: {orientation}")
        };
    }
}

答案 13 :(得分:-5)

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

然后在代码中你可以使用

public Orientation GetDefaultOrientation()
{
   return default(Orientation);
}