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

Например:

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

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

Ответ 1

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

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

Ответ 2

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

public enum Unit{ 
  [DisplayName("Hz")] Hertz, 
  [DisplayName("%V")] Volt 
} 

Ответ 3

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

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

Чтобы получить доступ, это просто: UnitEnum.Volt

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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


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

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

Ответ 7

Члены Enum не должны использоваться для отображения интерфейса пользователя. Но вы можете использовать простые приемы с DisplayName ("Отображаемое имя вашего имущества") для этого ниже.

//Enum
public enum ErrorCodes
{
      [DisplayName("U-volt")] UVolt = 2,
      [DisplayName("L-trip")] Ltrip = 5
}


//Here you can retrive Display name as bellow
public class MyClass{
     public void readEnumDisplayName(){
         String ErroCode = Enum.GetName(typeof(ErrorCodes), 5);    // Find Error Name using Integer value
          MemberInfo property = typeof(ErrorCodes).GetRuntimeField(ErroCode);     //Find Field
          var dd = property.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute;   //Find Display Attribute
          if (dd != null)  //Check if null
          {
             var name = dd.DisplayName;   //Retrive Display name
          }
      }
}

Ответ 8

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

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

public enum UnitType {
  Kilowatt,
  Kilovolt,
  Volt,
  Hertz,
  Ohm,
  Faraday
}

Поэтому я могу использовать их в раскрывающемся списке, например (когда мне нужно создать новый элемент, все, что мне нужно сделать, это добавить этот элемент в Enumeration...

ddl.Items.Clear();
foreach (string type in Enum.GetNames(typeof(UnitType)))
    ddl.Items.Add(type);

Я использую Space Separator, но обычно я использую подчеркивание для создания пробелов, например

public enum myType { Process_Time, Process_Order, Process_Invoices }

и элемент DropDownList будет

ddl.Items.Add(type.Replace("_", " "));

когда я хочу установить Type из DropDown, я использую Parse

UnitType unit = (UnitType)Enum.Parse(
                                 typeof(UnitType),
                                 ddl.SelectedValue.toString());

если вы используете Separator

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

Некоторые правила, чтобы иметь возможность писать лучший код

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

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

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

Я надеюсь, что смогу помочь кому-то.