Два варианта предлагают себя:
1) Используйте перечисление и добавьте атрибут Description к каждому значению. Затем вы можете довольно легко построить карту от значения до описания.
Преимущества:
- Все еще тип значения
- Можно использовать в операторах switch
Недостатки:
2) Не используйте перечисление .NET - используйте что-то более похожее на перечисления Java. Это в основном включает в себя написание открытого неизменяемого класса с частным конструктором и предоставление общедоступных (только для чтения) общих свойств / полей. Вот немного C #, чтобы продемонстрировать, что я имею в виду - надеюсь, вы лучше читаете C #, чем я пишу VB:)
public sealed class Reason
{
public static readonly Reason ServiceNotCovered = new Reason("SNCV");
public static readonly Reason MemberNotEligible = new Reason("MNEL");
private readonly string code;
private Reason(string code)
{
this.code = code;
}
public string Code
{
get { return code; }
}
}
Теперь, к сожалению, вы не можете включить это (по крайней мере, не в C # - я не знаю, является ли VB Select более гибким), но куда бы вы не включили 1023 *, стоит подумать о том, сможете ли вы обеспечить ту же функциональность внутри самого перечисления. Это хорошо ОО способ мышления об этом. Различные причины могут обеспечить различную функциональность посредством полиморфизма. Например:
public class Reason
{
public static readonly Reason ServiceNotCovered = new ServiceReason();
public static readonly Reason MemberNotEligible = new EligibilityReason();
private readonly string code;
private Reason(string code)
{
this.code = code;
}
public string Code
{
get { return code; }
}
public abstract void DoSomething();
private class ServiceReason : Reason
{
internal ServiceReason() : base("SVNC") {}
public override void DoSomething()
{
// Whatever
}
}
private class EligibiltyReason : Reason
{
internal EligibiltyReason() : base("MNEL") {}
public override void DoSomething()
{
// Do something else
}
}
}
Затем вы можете "сгруппировать" разные причины, которые имеют сходное поведение, создав столько производных типов, сколько есть групп - и вызывающему не нужно ничего о них знать.
Все это предполагает, что управление доступом VB работает так же, как и в C #, с точки зрения того, что вложенные типы могут обращаться к закрытым членам (в частности, к конструктору) своих внешних классов.
Это довольно многословное решение с точки зрения кода, но оно помогает сохранить весь процесс принятия решений относительно «enum» прямо в самом типе. Однако есть и другой недостаток, связанный с типом ссылки - поэтому вам нужно будет проверять на ничтожность обычным способом. С другой стороны, перечисления также не обеспечивают реальной защиты от неправильных значений - вы должны использовать Enum.IsDefined
, если хотите проверить аргумент.