![](/img/trans.png)
[英]Is there a name for this pattern? (C# compile-time type-safety with “params” args of different types)
[英]C# enum type-safety
有沒有辦法強制C#枚舉只接受幾個明確命名的常量之一,還是有另一個功能呢? C#參考有了這個想法:
可以將任意整數值分配給枚舉類型。 但是,您不應該這樣做,因為隱含的期望是枚舉變量只保存枚舉定義的值之一。 將任意值分配給枚舉類型的變量是為了引入高風險的錯誤。
(一種新的語言設計允許這種邋。。這讓我感到困惑。)
據我所知,你不能阻止C#允許枚舉和整數之間的轉換。
作為一種變通方法,您可以使用具有受限實例化的自定義類型。 用法看起來類似,但您也可以為此類型定義方法和運算符。
說你有這個枚舉:
enum DayOfWeek
{
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
您可以在其位置使用密封類。 優點是您可以免費進行比較(因為在這種情況下,值比較和參考比較是等效的)。 缺點是(像C#中的所有引用類型一樣),它可以為空。
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
該類的實例只能包含枚舉中定義的值,否則構造函數將不允許創建實例。
由於類是不可變的,因此值不能更改為未定義的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.