Например:
public enum Unit{
KW,
kV,
V,
Hz,
%V
}
В этом случае % является специальным символом. Так, как я могу поместить этот символ в перечисление?
Члены перечисления не должны использоваться для целей отображения пользовательского интерфейса. Для отображения они должны быть сопоставлены со строкой. Вы можете создать массив строк (или словарь), который отображает каждый член перечисления в строку для взаимодействия с пользователем.
Тем не менее, чтобы напрямую ответить на ваш вопрос, вы можете использовать Как указывает Хенк, это не сработает для \ uxxxxV
, где xxxx
- шестнадцатеричное число, представляющее кодовую точку Unicode для %
. Это далеко не рекомендуется. %
, поскольку этого нет в классах Unicode Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, Cf (буквы , цифры, соединительные и форматирующие символы). Только эти символы приемлемы для идентификаторов.
Я не уверен, почему вам нужны специальные символы в вашем перечислении, однако, если вы похожи на меня и вам нужно отображать имя лучше, чем, возможно, введите использование значений XmlEnumAttribute для Enum
Дополнительные сведения см. в моем блоге
Некоторые могут заявить, что перечисления предназначены только для кода, я должен не согласиться и использую функции для кодирования и отображения.
В вашем конкретном случае я бы использовал полное слово
public enum UnitType {
Kilowatt,
Kilovolt,
Volt,
Hertz,
Ohm,
Faraday
}
, поэтому я могу использовать их в раскрывающемся списке, например, как (когда мне нужно создать новый элемент, все, что мне нужно сделать, это добавить этот элемент в перечисление. ..
ddl.Items.Clear();
foreach (string type in Enum.GetNames(typeof(UnitType)))
ddl.Items.Add(type);
Я обычно использую разделитель пробелов, но обычно я использую подчеркивание для создания пробелов, например
public enum myType { Process_Time, Process_Order, Process_Invoices }
, а элемент DropDownList будет
ddl.Items.Add(type.Replace("_", " "));
, когда я хочу установить тип из DropDown, я использую Parse
UnitType unit = (UnitType)Enum.Parse(
typeof(UnitType),
ddl.SelectedValue.toString());
, конечно, если вы используете Separator
ddl.SelectedValue.toString().Replace(" ", "_"));
Некоторые правила , которые следует учитывать при написании лучшего кода
В качестве напоминания
Надеюсь, я смогу кому-нибудь помочь.
Даже если бы вы могли это сделать (а похоже, что не можете), это, вероятно, не лучшая идея, потому что вы бы смешивали как должно отображаться перечисление вместе с программным кодом для управления им. Лучшим вариантом было бы определить атрибут (или использовать существующий DisplayNameAttribute
) и аннотировать ваше перечисление именами в качестве дополнительных метаданных:
public enum Unit{
[DisplayName("Hz")] Hertz,
[DisplayName("%V")] Volt
}
Извините, но я только что понял, что не ответил на вопрос. Я не буду удалять свой ответ, потому что кто-то может найти эти фрагменты кода полезными.
Я полностью согласен с Томашем Петричеком, поэтому не буду повторять его ответ.
Вот мое решение проблемы. Я использую этот код около пяти лет. Я решил создать настраиваемый атрибут, чтобы использовать атрибут DisplayName для подписей и тому подобного.
Public Module MainModule
Public Sub Main()
Console.WriteLine(EnumEx.GetNumberFormatString(Unit.Volt), 120.13)
End Sub
End Module
Public Enum Unit
<NumberFormatString("{0} Hz"), DisplayName("Hertz")> Hz
<NumberFormatString("{0} %V"), DisplayName("%Volt")> pV
End Enum
<AttributeUsage(AttributeTargets.All)> _
Public NotInheritable Class NumberFormatStringAttribute
Inherits Attribute
Public Shared ReadOnly [Default] As NumberFormatStringAttribute = New NumberFormatStringAttribute
Private _format As String
Public Sub New()
Me.New(Char.MinValue)
End Sub
Public Sub New(ByVal format As String)
_format = format
End Sub
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If (obj Is Me) Then
Return True
End If
Dim oAttribute As NumberFormatStringAttribute = TryCast(obj, NumberFormatStringAttribute)
If (Not oAttribute Is Nothing) Then
Return (oAttribute.NumberFormatString = Me.NumberFormatString)
End If
Return False
End Function
Public Overrides Function GetHashCode() As Integer
Return Me.NumberFormatString.GetHashCode
End Function
Public Overrides Function IsDefaultAttribute() As Boolean
Return Me.Equals(NumberFormatStringAttribute.Default)
End Function
Public ReadOnly Property NumberFormatString() As String
Get
Return Me.NumberFormatStringValue
End Get
End Property
Private Property NumberFormatStringValue() As String
Get
Return _format
End Get
Set(ByVal value As String)
_format = value
End Set
End Property
End Class
Public NotInheritable Class EnumEx
Private Sub New()
End Sub
Public Shared Function GetNumberFormatString(ByVal value As Object) As String
Dim sResult As String = Nothing
Dim oFieldInfo As System.Reflection.FieldInfo = value.GetType.GetField(value.ToString)
If Not (oFieldInfo Is Nothing) Then
Dim oCustomAttributes() As Object = oFieldInfo.GetCustomAttributes(GetType(NumberFormatStringAttribute), True)
If (Not (oCustomAttributes Is Nothing)) AndAlso oCustomAttributes.Length > 0 Then
sResult = DirectCast(oCustomAttributes(0), NumberFormatStringAttribute).NumberFormatString
End If
End If
Return sResult
End Function
End Class
Этот ответ связан с ответом @Coppermill Я чувствую, что использование DescriptionAttribute более семантически правильно при работе с Enums
public enum ReportStatus
{
[Description("Reports that are running")] Running,
[Description("Reports that are pending to run")] Pending,
[Description("Reports that have errored while running")] Error,
[Description("Report completed successfully.")] Finished
}
Затем я прочитал из него следующее
public static bool IsNullable(this Type type)
{
if (!type.IsGenericType)
return false;
var g = type.GetGenericTypeDefinition();
return (g.Equals(typeof (Nullable<>)));
}
public static Type ConcreteType(this Type type)
{
if (IsNullable(type))
type = UnderlyingTypeOf(type);
return type;
}
.
public static string ReadDescription<T>(T enumMember)
{
if (typeof (T).IsNullable() && enumMember == null) return null;
var type = (typeof (T).ConcreteType());
var fi = type.GetField(enumMember.ToString());
var attributes = fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
if(attributes.Length == 0) return enumMember.ToString();
return attributes.Cast<DescriptionAttribute>().First().Description;
}
Тогда использование будет ReadDescription(ReportStatus.Running)
У меня также есть метод, который преобразует Enum в KeyValuePair Enumerable для привязки Enum к DropDown.