Я хочу написать общий класс, который принимает перечисления. Поскольку этот класс предназначен для реализации некоторых интерфейсов, основная цель состоит в том, чтобы иметь возможность обрабатывать перечисления как другие объекты, реализующие эти интерфейсы (например, для расширений списка и т. Д.). Следовательно, для образца перечислимогоОбщий класс для перечислений - проблема с литьем
public enum QEnum : int
{
xlNoValue = 0,
xlSomeValue = 1
}
public static class QEnumExtensions
{
public static string toString(this QEnum xThis)
{
...
}
public static QEnum toEnum(this string xThis)
{
...
}
}
Я хотел бы объявить общий класс таких, как
public class QEnumHolder<T> where T : struct, IConvertible
{
private T mxVal = default(T);
public QEnumHolder()
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
}
public QEnumHolder(T xVal)
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
mxVal = xVal;
}
static public implicit operator QEnumHolder<T>(T xVal)
{
return new QEnumHolder<T>(xVal);
}
static public implicit operator T(QEnumHolder<T> xVal)
{
return (T)xVal.mxVal;
}
public string toString()
{
if (mxVal is QEnum) return ((QEnum)Convert.ToInt32(mxVal)).toString();
...
}
public void fromString(string xString)
{
if (mxVal is QEnum)
mxVal = (???)xString.toEnum(); // problem
}
}
Все перечислений, которые мы используем реализовать функцию
- ToString(), который возвращает «хорошая» строка, которая может входить в comboBoxes и т. д.
- преобразование строки в перечисление, как указано выше
Следовательно, структура toString/toEnum в значительной степени дается. Проблема в том, что последняя строка кода помечена как «проблема». Я не знаю, как сообщить компилятору, что в этой ветке возвращаемый тип toEnum()
и T
будет таким же.
Я попытался обойти эту проблему, указав mxVal
как int
и используя Convert.ToInt32
всюду. Тем не менее, тогда я столкнулся с проблемой в operator T
, где у компилятора есть возражения против преобразования int
в T
(компилятор не может знать, что T
будет перечислять, поэтому я не могу использовать ни одно из преобразований «int to enum conversion» здесь на SO).
Как правило, C# использует верблюд-футляр и d для 'ToString()' вы должны переопределить. – Bauss
@Bauss: Я знаю, мне это не нравится. То же самое с Equals() и т. Д. - если вы не переопределяете его, вы получаете реализацию, которую вам не интересует, и никто не уведомляет вас. –
С этим дизайном много проблем. Если ваш класс содержит код типа 'is QEnum' и' (QEnum) что-то) ', т. Е. ** конкретные ** типы, то это ** не ** общий класс. Кроме того, у вас не может быть нескольких методов расширения «ToEnum (string)», которые отличаются только возвращаемым типом. –