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

Например:

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

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

Ответы [ 7 ]

30 голосов
/ 03 марта 2010

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

public enum Unit{ 
  [DisplayName("Hz")] Hertz, 
  [DisplayName("%V")] Volt 
} 
8 голосов
/ 03 марта 2010

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

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

4 голосов
/ 28 июля 2017

Просто чтобы зарегистрировать другой способ сделать это простым способом, вы можете определить «свой» перечислитель с константами.В вашем примере

public class UnitEnum
{
  public const string KW = "KW";
  public const string Volt = "%V";
}

Для доступа достаточно просто: UnitEnum.Volt

1 голос
/ 03 марта 2010

Этот ответ связан с ответом @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 для привязки Enum к DropDown.

0 голосов
/ 03 марта 2010

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


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

Вот мое решение проблемы. Я использую этот код около пяти лет. Я решил создать пользовательский атрибут, чтобы использовать атрибут 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 голосов
/ 03 марта 2010

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

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

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());

Конечно, если вы используете разделитель

 ddl.SelectedValue.toString().Replace(" ", "_"));

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

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

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

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

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

0 голосов
/ 03 марта 2010

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

Проверьте мой блог для более подробной информации

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

...