Насколько я знаю, вы не можете остановить C#, позволяя конверсии между перечислениями и целыми числами.
В качестве обходного пути вы можете вместо этого использовать специальный тип с ограниченным экземпляром. Использование будет выглядеть аналогично, но у вас также будет возможность определить методы и операторы для этого типа.
Скажем у вас есть это перечисление:
enum DayOfWeek
{
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
Вы можете использовать запечатанный класс на своем месте. Преимущество состоит в том, что вы получаете бесплатные сравнения (потому что сравнение значений и сравнительное сравнение эквивалентны для этого случая). Недостатком является то, что (как и все ссылочные типы в C#), он имеет значение NULL.
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);
}
}
Существует одна вещь, которую он делает хуже - теперь вы можете назначить '' null' к DayOfWeek', потому что это класс. – MarcinJuraszek
@MarcinJuraszek Вы правы. Я включил альтернативный подход. –
Подход «struct» дает еще одну проблему: вы можете создать дополнительное значение, вызвав конструкцию безразличия. Компилятор определяет его по умолчанию для каждой структуры независимо от того, что. – MarcinJuraszek