.net 如何在 C# 枚举中使用特殊字符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2373986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use a special char in a C# enum?
提问by Edumenna
For example:
例如:
public enum Unit{
KW,
kV,
V,
Hz,
%V
}
In this case % is a special character. So, how can I put this char in a enum?
在这种情况下 % 是一个特殊字符。那么,我怎样才能把这个字符放在一个枚举中呢?
采纳答案by Mehrdad Afshari
Enum members shouldn't be used for user interface display purposes. They should be mapped to a string in order to get displayed. You can create a string array (or a dictionary) that maps each enum member to a string for user interaction.
枚举成员不应用于用户界面显示目的。它们应该映射到一个字符串以便显示。您可以创建一个字符串数组(或字典),将每个枚举成员映射到一个字符串以供用户交互。
That said, to answer your question directly, you can use As Henk points out, this won't work for \uxxxxVwere xxxxis the hexadecimal number representing the Unicode code point for %. This is far from recommended.%as it's not in Unicode classes Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc, Cf (letters, digits, connecting, and formatting characters). Only these characters are acceptable for identifiers.
也就是说,要直接回答您的问题,您可以使用正如 Henk 指出的那样,这不会起作用,\uxxxxVwasxxxx是表示%. 这远非推荐。%因为它不在 Unicode 类 Lu、Ll、Lt、Lm、Lo、Nl、Mn、Mc、Nd、Pc、Cf(字母、数字、连接和格式化字符)中。标识符只能接受这些字符。
回答by Tomas Petricek
Even if you could do that (and it looks you can't), it probably wouldn't be a good idea, because you'd be mixing how the enum should be displayed with the program code to manipulate it. A better option would be to define an attribute (or use existing DisplayNameAttribute) and annotate your enum with names as additional meta-data:
即使您可以这样做(并且看起来您不能这样做),这也可能不是一个好主意,因为您会将枚举的显示方式与程序代码的显示方式混合在一起以对其进行操作。更好的选择是定义一个属性(或使用 existing DisplayNameAttribute)并使用名称作为附加元数据注释您的枚举:
public enum Unit{
[DisplayName("Hz")] Hertz,
[DisplayName("%V")] Volt
}
回答by HLourenco
Just to register another way to do that, in a simple way, you can define "your own" enumerator with constants. In your example
只是为了注册另一种方式来做到这一点,以一种简单的方式,您可以使用常量定义“您自己的”枚举器。在你的例子中
public class UnitEnum
{
public const string KW = "KW";
public const string Volt = "%V";
}
To access, it just: UnitEnum.Volt
要访问,它只是: UnitEnum.Volt
回答by Chris Marisic
This answer is related to the one from @Coppermill I feel using the DescriptionAttribute is more semantically correct when working with Enums
这个答案与@Coppermill 的答案有关,我觉得在使用 Enums 时使用 DescriptionAttribute 在语义上更正确
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
}
Then I read from it like such
然后我像这样阅读它
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;
}
Then usage would be ReadDescription(ReportStatus.Running)I also have a method that will convert an Enum into a KeyValuePair Enumerable for binding an Enum to a DropDown.
然后用法是ReadDescription(ReportStatus.Running)我还有一个方法可以将 Enum 转换为 KeyValuePair Enumerable 以将 Enum 绑定到 DropDown。
回答by AMissico
Sorry, but I just realized that I didn't answer the question. I will not delete my answer because someone may find these code snippets helpful.
对不起,但我刚刚意识到我没有回答这个问题。我不会删除我的答案,因为有人可能会发现这些代码片段很有帮助。
I agree completely with Tomas Petricek, so I will not repeat his answer.
我完全同意 Tomas Petricek 的观点,所以我不会重复他的回答。
Here is my solution to the problem. I been using this code for about five years. I decided to create a custom attribute in order to use the DisplayName attribute for captions and such.
这是我对问题的解决方案。我使用这个代码大约五年了。我决定创建一个自定义属性,以便将 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
回答by Udara Kasun
Enum members shouldn't be used for user interface display purposes. But you can use simple trickswith DisplayName("Your Property Display Name")for this matter as bellow.
枚举成员不应用于用户界面显示目的。但是你可以使用简单的技巧与显示名称(“你的财产显示名称”)这件事情的波纹管。
//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
}
}
}
回答by Coppermill
I'm not sure why you are after special characters in your enum, however if you are like me and you need to display a better name than perhaps type using the XmlEnumAttribute values for an Enum
我不确定为什么你在枚举中的特殊字符之后,但是如果你像我一样并且你需要显示一个更好的名称,而不是使用 XmlEnumAttribute 值键入一个枚举
Check out my blog for more details
查看我的博客了解更多详情
回答by balexandre
Some can state that Enumerations are for Code only, I must disagree and I use to Code and Display functionality.
有些人可以说枚举仅用于代码,我必须不同意并且我习惯于代码和显示功能。
In your particular case I would use the full word
在你的特殊情况下,我会使用完整的词
public enum UnitType {
Kilowatt,
Kilovolt,
Volt,
Hertz,
Ohm,
Faraday
}
So I can use them in a Dropdown for example as (when I need to create a new item, all I need to do is append that item into the Enumeration...
所以我可以在下拉菜单中使用它们,例如(当我需要创建一个新项目时,我需要做的就是将该项目附加到枚举中......
ddl.Items.Clear();
foreach (string type in Enum.GetNames(typeof(UnitType)))
ddl.Items.Add(type);
I tend to use Space Separator, but I normally use underscore to make spaces, like
我倾向于使用空格分隔符,但我通常使用下划线来制作空格,例如
public enum myType { Process_Time, Process_Order, Process_Invoices }
and the DropDownList item would be
并且 DropDownList 项目将是
ddl.Items.Add(type.Replace("_", " "));
when I want to set the Type from the DropDown, I use the Parse
当我想从 DropDown 设置类型时,我使用 Parse
UnitType unit = (UnitType)Enum.Parse(
typeof(UnitType),
ddl.SelectedValue.toString());
off course, if you use Separator
当然,如果你使用 Separator
ddl.SelectedValue.toString().Replace(" ", "_"));
Some rulesto have in consideration to write better code
编写更好的代码时需要考虑的一些规则
- Always write Typeto an Enum, in you case Unit should be UnitType
- Use Title Case for Enumeration Objects
- 始终将Type写入Enum,在这种情况下 Unit 应该是UnitType
- 枚举对象的标题大小写
As a reminder
提醒一句
- You can use an Enum in a Bit Operation adding [Flags] keyword
- You can specify the integer value of the Enum if you don't want to have: 0, 1, 2, 3...
- 您可以在位操作中使用枚举添加 [Flags] 关键字
- 如果你不想有,你可以指定 Enum 的整数值:0, 1, 2, 3 ...
I hope I can help someone.
我希望我能帮助别人。

