在c#中,是否有可能用属性装饰Enum类型或做一些其他事情来指定默认值应该是什么,而不改变值?由于某种原因,所需的数字可能是固定不变的,而且仍然可以控制默认值是很方便的。
enum Orientation
{
None = -1,
North = 0,
East = 1,
South = 2,
West = 3
}
Orientation o; // Is 'North' by default.
在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);
}
其他回答
如果0不是合适的默认值,你可以使用组件模型为枚举定义一个变通方法:
[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#语言默认值,但提供了一种方法来指示(并获得)所需的默认值。
还有一种方法可能会有帮助——使用某种“别名”。 例如:
public enum Status
{
New = 10,
Old = 20,
Actual = 30,
// Use Status.Default to specify default status in your code.
Default = New
}
在这种情况下,不要依赖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}")
};
}
}
如果你将默认enum定义为最小值的enum,你可以使用这个:
public enum MyEnum { His = -1, Hers = -2, Mine = -4, Theirs = -3 }
var firstEnum = ((MyEnum[])Enum.GetValues(typeof(MyEnum)))[0];
firstEnum == Mine.
这并没有假设枚举值为零。
默认值是定义中的第一个。例如:
public enum MyEnum{His,Hers,Mine,Theirs}
Enum.GetValues(typeOf(MyEnum)).GetValue(0);
这将返回他的