C# 选择 Enum 类型的默认值而不必更改值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/529929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Choosing the default value of an Enum type without having to change values
提问by xyz
In C#, is it possible to decorate an Enum type with an attribute or do something else to specify what the default value should be, without having the change the values? The numbers required might be set in stone for whatever reason, and it'd be handy to still have control over the default.
在 C# 中,是否可以使用属性装饰 Enum 类型或执行其他操作来指定默认值应该是什么,而无需更改值?无论出于何种原因,所需的数字都可能是一成不变的,并且仍然可以控制默认值会很方便。
enum Orientation
{
None = -1,
North = 0,
East = 1,
South = 2,
West = 3
}
Orientation o; // Is 'North' by default.
采纳答案by James Curran
The default for an enum
(in fact, any value type) is 0 -- even if that is not a valid value for that enum
. It cannot be changed.
an enum
(实际上,任何值类型)的默认值是 0——即使这不是 that 的有效值enum
。它无法更改。
回答by Joe
An enum's default is whatever enumeration equates to zero. I don't believe this is changeable by attribute or other means.
枚举的默认值是枚举等于零的任何值。我不相信这是可以通过属性或其他方式改变的。
(MSDN says: "The default value of an enum E is the value produced by the expression (E)0.")
(MSDN 说:“枚举 E 的默认值是表达式 (E)0 产生的值。”)
回答by Cian
Actually an enum
's default is the first element in the enum
whose value is 0
.
实际上 anenum
的默认enum
值是其值为的第一个元素0
。
So for example:
例如:
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;
回答by Avram
You can't, but if you want, you can do some trick. :)
你不能,但如果你愿意,你可以做一些小把戏。:)
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;
}
usage of this struct as simple enum.
where you can create p.a == Orientation.East (or any value that you want) by default
to use the trick itself, you need to convert from int by code.
there the implementation:
将此结构用作简单枚举。
默认情况下,您可以在其中创建 pa == 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
回答by Avram
The default value of any enum is zero. So if you want to set one enumerator to be the default value, then set that one to zero and all other enumerators to non-zero (the first enumerator to have the value zero will be the default value for that enum if there are several enumerators with the value zero).
任何枚举的默认值为零。因此,如果您想将一个枚举数设置为默认值,则将该枚举数设置为零,并将所有其他枚举数设置为非零(如果有多个枚举数,则第一个具有零值的枚举数将是该枚举的默认值)值为零)。
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'
If your enumerators don't need explicit values, then just make sure the first enumerator is the one you want to be the default enumerator since "By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1." (C# reference)
如果您的枚举器不需要显式值,那么只需确保第一个枚举器是您想要成为默认枚举器的那个,因为“默认情况下,第一个枚举器的值为 0,并且每个后续枚举器的值增加了1.” (C# 参考)
enum Orientation
{
None, //default value since it is the first enumerator
North,
East,
South,
West
}
Orientation o; // initialized to 'None'
回答by Ruslan Urban
[DefaultValue(None)]
public enum Orientation
{
None = -1,
North = 0,
East = 1,
South = 2,
West = 3
}
Then in the code you can use
然后在代码中你可以使用
public Orientation GetDefaultOrientation()
{
return default(Orientation);
}
回答by Tony Hopkinson
The default is the first one in the definition. For example:
默认是定义中的第一个。例如:
public enum MyEnum{His,Hers,Mine,Theirs}
Enum.GetValues(typeOf(MyEnum)).GetValue(0);
This will return His
这将返回 His
回答by David
If zero doesn't work as the proper default value, you can use the component model to define a workaround for the enum:
如果零不能作为正确的默认值,您可以使用组件模型为枚举定义解决方法:
[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);
}
}
}
and then you can call:
然后你可以打电话:
Orientation o = Utilities.GetDefaultValue<Orientation>();
System.Diagnostics.Debug.Print(o.ToString());
Note: you will need to include the following line at the top of the file:
注意:您需要在文件顶部包含以下行:
using System.ComponentModel;
This does not change the actual C# language default value of the enum, but gives a way to indicate (and get) the desired default value.
这不会更改枚举的实际 C# 语言默认值,但提供了一种指示(和获取)所需默认值的方法。
回答by Dmitry Pavlov
One more way that might be helpful - to use some kind of "alias". For example:
另一种可能有用的方法 - 使用某种“别名”。例如:
public enum Status
{
New = 10,
Old = 20,
Actual = 30,
// Use Status.Default to specify default status in your code.
Default = New
}
回答by Moumit
The default value of enum is the enummember equal to 0 or the first element(if value is not specified)
... But i have faced critical problems using enum in my projects and overcome by doing something below ... How ever my need was related to class level ...
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
}
and get expected result
并得到预期的结果
CDDtype d1= new CDDtype();
CDDtype d2 = new CDDtype { Id = 50 };
Console.Write(d1.DDType);//None
Console.Write(d2.DDType);//None
Now what if value is coming from DB .... Ok in this scenario... pass value in below function and it will convertthe value to enum ...below function handled various scenario and it's generic... and believe me it is very fast ..... :)
现在如果值来自 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);
}