有没有办法强制 C# 枚举只接受几个明确命名的常量之一,或者有没有其他功能可以实现这一点?C# 参考文献中有这个事后的解释:可以向枚举类型分配任意整数值。但是,不应该这样做,因为隐含的期望是一个枚举变量将只保存由枚举定义的值之一。将任意值分配给枚举类型的变量将引入高风险的错误。(有一种新语言被设计用于允许这种松散性。这让我感到困惑。)
enum DayOfWeek
{
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
sealed class DayOfWeek
{
public static readonly DayOfWeek Monday = new DayOfWeek(0);
public static readonly DayOfWeek Tuesday = new DayOfWeek(1);
public static readonly DayOfWeek Wednesday = new DayOfWeek(2);
public static readonly DayOfWeek Thursday = new DayOfWeek(3);
public static readonly DayOfWeek Friday = new DayOfWeek(4);
public static readonly DayOfWeek Saturday = new DayOfWeek(5);
public static readonly DayOfWeek Sunday = new DayOfWeek(6);
private readonly int _value;
private DayOfWeek(int value)
{
_value = value;
}
}
或者你可以使用结构体。优点是它不可为空,因此更类似于枚举。缺点是你必须手动实现比较代码:
struct DayOfWeek
{
public static readonly DayOfWeek Monday = new DayOfWeek(0);
public static readonly DayOfWeek Tuesday = new DayOfWeek(1);
public static readonly DayOfWeek Wednesday = new DayOfWeek(2);
public static readonly DayOfWeek Thursday = new DayOfWeek(3);
public static readonly DayOfWeek Friday = new DayOfWeek(4);
public static readonly DayOfWeek Saturday = new DayOfWeek(5);
public static readonly DayOfWeek Sunday = new DayOfWeek(6);
private readonly int _value;
private DayOfWeek(int value)
{
_value = value;
}
public bool Equals(DayOfWeek other)
{
return _value == other._value;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is DayOfWeek && Equals((DayOfWeek)obj);
}
public override int GetHashCode()
{
return _value;
}
public static bool operator ==(DayOfWeek op1, DayOfWeek op2)
{
return op1.Equals(op2);
}
public static bool operator !=(DayOfWeek op1, DayOfWeek op2)
{
return !(op1 == op2);
}
}
将任何整数转换为枚举类型主要是出于性能原因,但是作为值类型实现的枚举无法防止包含未定义的值。考虑以下枚举:
public enum Condition {
Right = 1,
Wrong = 2
}
public class Demo {
public Condition Cond;
}
Cond
成员变量将具有(Condition)0
未定义的值。public sealed class SafeEnum<T> where T : struct {
public T Value { get; private set; }
public SafeEnum(T value) {
if (!(value is Enum)) {
throw new ArgumentException("The type is not an enumeration.");
}
if (!Enum.IsDefined(typeof(T), value)) {
throw new ArgumentException("The value is not defined in the enumeration.");
}
Value = value;
}
}
例子:
var cond = new SafeEnum<Condition>(Condition.Right); // works
Condition d = cond.Value;
var cond = new SafeEnum<int>(42); // not an enum
var cond = new SafeEnum<Condition>((Condition)42); // not defined
该类的实例只能包含在枚举中定义的值,否则构造函数将不允许创建该实例。
由于该类是不可变的,因此其值不能更改为未定义的值。
null
赋值给DayOfWeek
,因为它是一个类。 - MarcinJuraszek