在c#中,是否有可能用属性装饰Enum类型或做一些其他事情来指定默认值应该是什么,而不改变值?由于某种原因,所需的数字可能是固定不变的,而且仍然可以控制默认值是很方便的。

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

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

当前回答

enum的默认值是等于0的枚举成员或第一个元素(如果没有指定value)…但我在我的项目中使用枚举遇到了严重的问题,并通过做下面的事情来克服…无论我的需求是如何与阶级水平相关的……

    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 ....在这种情况下……将值传递给下面的函数,它会将值转换为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);
    }

其他回答

enum的默认值是等于0的枚举成员或第一个元素(如果没有指定value)…但我在我的项目中使用枚举遇到了严重的问题,并通过做下面的事情来克服…无论我的需求是如何与阶级水平相关的……

    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 ....在这种情况下……将值传递给下面的函数,它会将值转换为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);
    }

enum(实际上,任何值类型)的默认值是0——即使这不是该enum的有效值。这是无法改变的。

在这种情况下,不要依赖enum值。设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
}

然后使用一种方法来获得魔数。你可以引入一个扩展方法并像这样使用它:

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

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

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

还有一种方法可能会有帮助——使用某种“别名”。 例如:

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

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