Как я могу использовать специальный символ в перечислении C#?

Например:

public enum Unit{
  KW,
  kV,
  V,
  Hz,
  %V
}

В этом случае % является специальным символом. Так, как я могу поместить этот символ в перечисление?

10
задан AMissico 3 March 2010 в 19:19
поделиться

6 ответов

Члены перечисления не должны использоваться для целей отображения пользовательского интерфейса. Для отображения они должны быть сопоставлены со строкой. Вы можете создать массив строк (или словарь), который отображает каждый член перечисления в строку для взаимодействия с пользователем.

Тем не менее, чтобы напрямую ответить на ваш вопрос, вы можете использовать \ uxxxxV , где xxxx - шестнадцатеричное число, представляющее кодовую точку Unicode для % . Это далеко не рекомендуется. Как указывает Хенк, это не сработает для % , поскольку этого нет в классах Unicode Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, Cf (буквы , цифры, соединительные и форматирующие символы). Только эти символы приемлемы для идентификаторов.

9
ответ дан 3 December 2019 в 13:34
поделиться

Я не уверен, почему вам нужны специальные символы в вашем перечислении, однако, если вы похожи на меня и вам нужно отображать имя лучше, чем, возможно, введите использование значений XmlEnumAttribute для Enum

Дополнительные сведения см. в моем блоге

http://www.bryanavery.co.uk/post/2010/01/08/How-do-you-retrieving-the- XmlEnumAttribute-values-for-an-Enum.aspx

0
ответ дан 3 December 2019 в 13:34
поделиться

Некоторые могут заявить, что перечисления предназначены только для кода, я должен не согласиться и использую функции для кодирования и отображения.

В вашем конкретном случае я бы использовал полное слово

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(" ", "_"));

Некоторые правила , которые следует учитывать при написании лучшего кода

  • Всегда пишите Type в Enum, в вашем случае Unit должен быть UnitType
  • Используйте заголовок для объектов перечисления

В качестве напоминания

  • Вы можете использовать Enum в битовой операции, добавив ключевое слово [Flags]
  • . Вы можете указать целочисленное значение Enum, если вы этого не сделаете. хочу иметь: 0, 1, 2, 3 ...

Надеюсь, я смогу кому-нибудь помочь.

-2
ответ дан 3 December 2019 в 13:34
поделиться

Даже если бы вы могли это сделать (а похоже, что не можете), это, вероятно, не лучшая идея, потому что вы бы смешивали как должно отображаться перечисление вместе с программным кодом для управления им. Лучшим вариантом было бы определить атрибут (или использовать существующий DisplayNameAttribute ) и аннотировать ваше перечисление именами в качестве дополнительных метаданных:

public enum Unit{ 
  [DisplayName("Hz")] Hertz, 
  [DisplayName("%V")] Volt 
} 
32
ответ дан 3 December 2019 в 13:34
поделиться

Извините, но я только что понял, что не ответил на вопрос. Я не буду удалять свой ответ, потому что кто-то может найти эти фрагменты кода полезными.


Я полностью согласен с Томашем Петричеком, поэтому не буду повторять его ответ.

Вот мое решение проблемы. Я использую этот код около пяти лет. Я решил создать настраиваемый атрибут, чтобы использовать атрибут 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
0
ответ дан 3 December 2019 в 13:34
поделиться

Этот ответ связан с ответом @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.

1
ответ дан 3 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: