Ответ 1
В основе моего решения лежит struct
, который может обернуть значения Enum
и переопределить ToString()
.
Введите EnumWrapper
:
public struct EnumWrapper
{
private readonly Enum e;
public EnumWrapper(Enum e) {
this.e = e;
}
public static implicit operator Enum(EnumWrapper wrapper) {
return wrapper.e;
}
public static explicit operator EnumWrapper(Enum e) {
return new EnumWrapper(e);
}
public override string ToString() {
return e.ToStringFriendly();
}
}
Метод ToStringFriendly()
определяется как метод расширения на Enum
:
using System.Text.RegularExpressions;
public static class _Extensions
{
public static string ToStringFriendly(this Enum e)
{
string s = e.ToString();
// enforce a charset: letters, numbers, and underscores
s = Regex.Replace(s, "[^A-Za-z0-9_]", "");
// separate numbers from letters
s = Regex.Replace(s, "([a-zA-Z])([0-9])", "$1 $2");
// separate letters from numbers
s = Regex.Replace(s, "([0-9])([a-zA-Z])", "$1 $2");
// space lowercases before uppercase (word boundary)
s = Regex.Replace(s, "([a-z])([A-Z])", "$1 $2");
// see that the nice pretty capitalized words are spaced left
s = Regex.Replace(s, "(?!^)([^ _])([A-Z][a-z]+)", "$1 $2");
// replace double underscores with colon-space delimiter
s = Regex.Replace(s, "__", ": ");
// finally replace single underscores with hyphens
s = Regex.Replace(s, "_", "-");
return s;
}
}
Теперь, чтобы добавить любое значение Enum
в ComboBox, например,
comboBox.Items.Add((EnumWrapper)MyEnum.SomeValue);
И вернуть его (после нулевого тестирования, конечно):
MyEnum myValue = (MyEnum)(Enum)(EnumWrapper)comboBox.SelectedItem;
И что это. Каковы же плюсы и минусы этого подхода?
Плюсы:
- Вы можете передавать значения перечисления (почти) непосредственно в свои элементы управления и из них. Просто отбрасывайте назад и вперед в/из
EnumWrapper
. - Это хорошо работает для всех значений
Enum
с паскалем с несколькими особыми случаями. Одним из примеров может быть значение, называемоеMyValue__DescriptionOf123_ENUMValue
, которое вышло бы изToStringFriendly()
как "My Value: Описание значения 123-ENUM". - Механика (a
struct
и метод расширения) может быть написана один раз и спрятана. В каждомEnum
нет дополнительного кодирования. Это означает, что он отлично работает, как указано выше для перечислений, которые вы не пишете, предполагая случай Паскаля, который в .NET является хорошим предположением. Примечание: вот почему я сказал бы этот ответ, какой бы изящной она ни была, не лучшее решение, чем мое, поскольку для этого требуется добавить атрибутTypeConverter
каждыйEnum
.
Против:
- Это не поддерживает пользовательские описания или несколько языков. Например, значение, подобное
Encoding.EBCDIC
, всегда будет отображаться как "EBCDIC" и не позволяет вам вручную вводить "расширенный двоично-кодированный код децимального обмена", а тем более другие языки.
Будущая работа
Можно добавить пользовательские описания и многоязычную поддержку, изменив ToStringFriendly()
, чтобы выполнить поиск по языку для этого значения перед де-Паскалем.
Подробнее о весе Regex см. этот поток.