Вот еще одна интересная идея, которая учитывает пользовательское поведение, доступное в Java. Я придумал следующий Enumeration
базовый класс:
public abstract class Enumeration<T>
where T : Enumeration<T>
{
protected static int nextOrdinal = 0;
protected static readonly Dictionary<int, Enumeration<T>> byOrdinal = new Dictionary<int, Enumeration<T>>();
protected static readonly Dictionary<string, Enumeration<T>> byName = new Dictionary<string, Enumeration<T>>();
protected readonly string name;
protected readonly int ordinal;
protected Enumeration(string name)
: this (name, nextOrdinal)
{
}
protected Enumeration(string name, int ordinal)
{
this.name = name;
this.ordinal = ordinal;
nextOrdinal = ordinal + 1;
byOrdinal.Add(ordinal, this);
byName.Add(name, this);
}
public override string ToString()
{
return name;
}
public string Name
{
get { return name; }
}
public static explicit operator int(Enumeration<T> obj)
{
return obj.ordinal;
}
public int Ordinal
{
get { return ordinal; }
}
}
Он имеет параметр типа в основном просто для того, чтобы порядковый номер работал правильно для различных производных перечислений. Operator
пример Джона Скита из его ответа на другой вопрос (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) выше становится:
public class Operator : Enumeration<Operator>
{
public static readonly Operator Plus = new Operator("Plus", (x, y) => x + y);
public static readonly Operator Minus = new Operator("Minus", (x, y) => x - y);
public static readonly Operator Times = new Operator("Times", (x, y) => x * y);
public static readonly Operator Divide = new Operator("Divide", (x, y) => x / y);
private readonly Func<int, int, int> op;
// Prevent other top-level types from instantiating
private Operator(string name, Func<int, int, int> op)
:base (name)
{
this.op = op;
}
public int Execute(int left, int right)
{
return op(left, right);
}
}
Это дает несколько преимуществ.
- Порядковая поддержка
- Преобразование в
string
и int
, что делает операторы переключения осуществимыми
- GetType () выдаст одинаковый результат для каждого из значений производного типа перечисления.
- Статические методы из
System.Enum
могут быть добавлены к базовому классу перечисления, чтобы обеспечить те же функции.