За последние пару недель я испытывал некоторые головные боли с любопытно повторяющимся шаблоном .
Исходя из этих двух моих вопросов:
Как улучшить следующий пример:
public class DocketType : Enumeration<DocketType, int, string>
{
public static DocketType Withdrawal = new DocketType(2, "Withdrawal");
public static DocketType Installation = new DocketType(3, "Installation");
private DocketType(int docketTypeId, string description)
: base(docketTypeId, description) { }
}
Мне нужен статический метод, который мне не нужно повторять в классе Enumeration
:
public abstract class Enumeration<TEnum, X, Y> : IComparable
where TEnum : Enumeration<TEnum, X, Y>
{
protected Enumeration(X value, Y displayName)
{
AddToStaticCache(this);
}
public static TEnum Resolve(X value)
{
return Cache[value] as TEnum;
}
}
Проблема с этим, как вы увидите из моего второго связанного вопроса, состоит в том, что вызов Enumeration<DocketType, int, string>.Resolve(X value);
не вызывает создания экземпляров DocketType
статических объектов.
Я не против полностью переписать это с нуля. Я знаю, что это большой запах кода. В настоящее время, чтобы это работало, мой базовый класс имеет защищенный статический метод ChildResolve
, и я добавил Resolve
к каждому из моих классов перечисления. Противные вещи!
ОТВЕТ:
Кажется, не было хорошей альтернативы шаблону, поэтому я придерживался шаблона, черпал вдохновение из принятого ответа и придумал следующее:
static Enumeration()
{
GetAll();
}
public static void GetAll()
{
var type = typeof(TEnum);
var fields = type.GetFields(BindingFlags.Public |
BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach (var info in fields)
{
var locatedValue = info.GetValue(null) as Enumeration<TEnum, X, Y>;
Cache.Add(locatedValue.Value, locatedValue);
}
}
Это тот же код, который используется в примере проекта CodeCampServer MVC, поэтому я чувствую себя менее грязным при его использовании!