我有以下内容 enum
public enum myEnum
{
ThisNameWorks,
This Name doesn't work
Neither.does.this;
}
Run Code Online (Sandbox Code Playgroud)
enum带有"友好名字"的s 不可能吗?
Tho*_*que 374
你可以使用该Description属性,如Yuriy建议的那样.以下扩展方法可以轻松获取枚举的给定值的描述:
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
FieldInfo field = type.GetField(name);
if (field != null)
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
{
return attr.Description;
}
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
public enum MyEnum
{
[Description("Description for Foo")]
Foo,
[Description("Description for Bar")]
Bar
}
MyEnum x = MyEnum.Foo;
string description = x.GetDescription();
Run Code Online (Sandbox Code Playgroud)
RaY*_*ell 78
枚举值名称必须遵循与C#中所有标识符相同的命名规则,因此只有名字是正确的.
Mar*_*ter 33
如果您有以下枚举:
public enum MyEnum {
First,
Second,
Third
}
Run Code Online (Sandbox Code Playgroud)
您可以声明扩展方法MyEnum(就像任何其他类型一样).我只是掀起了这个:
namespace Extension {
public static class ExtensionMethods {
public static string EnumValue(this MyEnum e) {
switch (e) {
case MyEnum.First:
return "First Friendly Value";
case MyEnum.Second:
return "Second Friendly Value";
case MyEnum.Third:
return "Third Friendly Value";
}
return "Horrible Failure!!";
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用此扩展方法,以下内容现在是合法的:
Console.WriteLine(MyEnum.First.EnumValue());
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!!
MRG*_*MRG 14
您可以使用该Description属性获取该友好名称.您可以使用以下代码:
public static string ToStringEnums(Enum en)
{
Type type = en.GetType();
MemberInfo[] memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
return ((DescriptionAttribute)attrs[0]).Description;
}
return en.ToString();
}
Run Code Online (Sandbox Code Playgroud)
您希望使用此方法的示例:当您的枚举值为EncryptionProviderType并且您想要enumVar.Tostring()返回"加密提供程序类型"时.
先决条件:应使用属性应用所有枚举成员[Description("String to be returned by Tostring()")].
枚举示例:
enum ExampleEnum
{
[Description("One is one")]
ValueOne = 1,
[Description("Two is two")]
ValueTow = 2
}
Run Code Online (Sandbox Code Playgroud)
在你的课堂上,你会像这样使用它:
ExampleEnum enumVar = ExampleEnum.ValueOne;
Console.WriteLine(ToStringEnums(enumVar));
Run Code Online (Sandbox Code Playgroud)
Tra*_*ife 10
这个技巧的一个问题是描述属性不能被本地化.我喜欢Sacha Barber的一种技术,他在那里创建了自己的Description属性版本,该属性将从相应的资源管理器中获取值.
http://www.codeproject.com/KB/WPF/FriendlyEnums.aspx
虽然本文是围绕WPF开发人员绑定到枚举时通常遇到的问题,但您可以直接跳转到他创建LocalizableDescriptionAttribute的部分.
已经发布了一些很棒的解决方案.当我遇到这个问题时,我想要双向:将枚举转换为描述,并将匹配描述的字符串转换为枚举.
我有两个变种,慢和快.两者都从枚举转换为字符串,字符串转换为枚举.我的问题是我有这样的枚举,其中一些元素需要属性,有些则不需要.我不想将属性放在不需要它们的元素上.我目前总共有大约一百个:
public enum POS
{
CC, // Coordinating conjunction
CD, // Cardinal Number
DT, // Determiner
EX, // Existential there
FW, // Foreign Word
IN, // Preposision or subordinating conjunction
JJ, // Adjective
[System.ComponentModel.Description("WP$")]
WPDollar, //$ Possessive wh-pronoun
WRB, // Wh-adverb
[System.ComponentModel.Description("#")]
Hash,
[System.ComponentModel.Description("$")]
Dollar,
[System.ComponentModel.Description("''")]
DoubleTick,
[System.ComponentModel.Description("(")]
LeftParenth,
[System.ComponentModel.Description(")")]
RightParenth,
[System.ComponentModel.Description(",")]
Comma,
[System.ComponentModel.Description(".")]
Period,
[System.ComponentModel.Description(":")]
Colon,
[System.ComponentModel.Description("``")]
DoubleBackTick,
};
Run Code Online (Sandbox Code Playgroud)
解决这个问题的第一种方法很慢,并且基于我在这里和网络上看到的建议.它很慢,因为我们反映每次转换:
using System;
using System.Collections.Generic;
namespace CustomExtensions
{
/// <summary>
/// uses extension methods to convert enums with hypens in their names to underscore and other variants
public static class EnumExtensions
{
/// <summary>
/// Gets the description string, if available. Otherwise returns the name of the enum field
/// LthWrapper.POS.Dollar.GetString() yields "$", an impossible control character for enums
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string GetStringSlow(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
System.Reflection.FieldInfo field = type.GetField(name);
if (field != null)
{
System.ComponentModel.DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(System.ComponentModel.DescriptionAttribute)) as System.ComponentModel.DescriptionAttribute;
if (attr != null)
{
//return the description if we have it
name = attr.Description;
}
}
}
return name;
}
/// <summary>
/// Converts a string to an enum field using the string first; if that fails, tries to find a description
/// attribute that matches.
/// "$".ToEnum<LthWrapper.POS>() yields POS.Dollar
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T ToEnumSlow<T>(this string value) //, T defaultValue)
{
T theEnum = default(T);
Type enumType = typeof(T);
//check and see if the value is a non attribute value
try
{
theEnum = (T)Enum.Parse(enumType, value);
}
catch (System.ArgumentException e)
{
bool found = false;
foreach (T enumValue in Enum.GetValues(enumType))
{
System.Reflection.FieldInfo field = enumType.GetField(enumValue.ToString());
System.ComponentModel.DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(System.ComponentModel.DescriptionAttribute)) as System.ComponentModel.DescriptionAttribute;
if (attr != null && attr.Description.Equals(value))
{
theEnum = enumValue;
found = true;
break;
}
}
if( !found )
throw new ArgumentException("Cannot convert " + value + " to " + enumType.ToString());
}
return theEnum;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题是你每次都在做反思.我没有测量过这样做的性能,但似乎令人担忧.更糟糕的是,我们反复计算这些昂贵的转换,而不是缓存它们.
相反,我们可以使用静态构造函数来填充一些带有此转换信息的字典,然后在需要时查找此信息.显然静态类(扩展方法所需)可以有构造函数和字段:)
using System;
using System.Collections.Generic;
namespace CustomExtensions
{
/// <summary>
/// uses extension methods to convert enums with hypens in their names to underscore and other variants
/// I'm not sure this is a good idea. While it makes that section of the code much much nicer to maintain, it
/// also incurs a performance hit via reflection. To circumvent this, I've added a dictionary so all the lookup can be done once at
/// load time. It requires that all enums involved in this extension are in this assembly.
/// </summary>
public static class EnumExtensions
{
//To avoid collisions, every Enum type has its own hash table
private static readonly Dictionary<Type, Dictionary<object,string>> enumToStringDictionary = new Dictionary<Type,Dictionary<object,string>>();
private static readonly Dictionary<Type, Dictionary<string, object>> stringToEnumDictionary = new Dictionary<Type, Dictionary<string, object>>();
static EnumExtensions()
{
//let's collect the enums we care about
List<Type> enumTypeList = new List<Type>();
//probe this assembly for all enums
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
Type[] exportedTypes = assembly.GetExportedTypes();
foreach (Type type in exportedTypes)
{
if (type.IsEnum)
enumTypeList.Add(type);
}
//for each enum in our list, populate the appropriate dictionaries
foreach (Type type in enumTypeList)
{
//add dictionaries for this type
EnumExtensions.enumToStringDictionary.Add(type, new Dictionary<object,string>() );
EnumExtensions.stringToEnumDictionary.Add(type, new Dictionary<string,object>() );
Array values = Enum.GetValues(type);
//its ok to manipulate 'value' as object, since when we convert we're given the type to cast to
foreach (object value in values)
{
System.Reflection.FieldInfo fieldInfo = type.GetField(value.ToString());
//check for an attribute
System.ComponentModel.DescriptionAttribute attribute =
Attribute.GetCustomAttribute(fieldInfo,
typeof(System.ComponentModel.DescriptionAttribute)) as System.ComponentModel.DescriptionAttribute;
//populate our dictionaries
if (attribute != null)
{
EnumExtensions.enumToStringDictionary[type].Add(value, attribute.Description);
EnumExtensions.stringToEnumDictionary[type].Add(attribute.Description, value);
}
else
{
EnumExtensions.enumToStringDictionary[type].Add(value, value.ToString());
EnumExtensions.stringToEnumDictionary[type].Add(value.ToString(), value);
}
}
}
}
public static string GetString(this Enum value)
{
Type type = value.GetType();
string aString = EnumExtensions.enumToStringDictionary[type][value];
return aString;
}
public static T ToEnum<T>(this string value)
{
Type type = typeof(T);
T theEnum = (T)EnumExtensions.stringToEnumDictionary[type][value];
return theEnum;
}
}
}
Run Code Online (Sandbox Code Playgroud)
看看转换方法现在有多紧张.我能想到的唯一缺陷是,这需要所有转换后的枚举都在当前程序集中.此外,我只打扰导出的枚举,但如果你愿意,你可以改变它.
这是如何调用方法
string x = LthWrapper.POS.Dollar.GetString();
LthWrapper.POS y = "PRP$".ToEnum<LthWrapper.POS>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
146103 次 |
| 最近记录: |