Bor*_*ens 265 c# enums tostring
我的枚举包含以下值:
private enum PublishStatusses{
NotCompleted,
Completed,
Error
};
Run Code Online (Sandbox Code Playgroud)
我希望能够以用户友好的方式输出这些值.
我不需要能够再次从字符串变为值.
小智 341
我用扩展方法做到这一点:
public enum ErrorLevel
{
None,
Low,
High,
SoylentGreen
}
public static class ErrorLevelExtensions
{
public static string ToFriendlyString(this ErrorLevel me)
{
switch(me)
{
case ErrorLevel.None:
return "Everything is OK";
case ErrorLevel.Low:
return "SNAFU, if you know what I mean.";
case ErrorLevel.High:
return "Reaching TARFU levels";
case ErrorLevel.SoylentGreen:
return "ITS PEOPLE!!!!";
default:
return "Get your damn dirty hands off me you FILTHY APE!";
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ray*_*sen 337
我使用Description
System.ComponentModel命名空间中的属性.只需装饰枚举:
private enum PublishStatusValue
{
[Description("Not Completed")]
NotCompleted,
Completed,
Error
};
Run Code Online (Sandbox Code Playgroud)
然后使用此代码检索它:
public static string GetDescription<T>(this T enumerationValue)
where T : struct
{
Type type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
//Tries to find a DescriptionAttribute for a potential friendly name
//for the enum
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
//Pull out the description value
return ((DescriptionAttribute)attrs[0]).Description;
}
}
//If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString();
}
Run Code Online (Sandbox Code Playgroud)
ann*_*ata 70
也许我错过了一些东西,但Enum.GetName出了什么问题?
public string GetName(PublishStatusses value)
{
return Enum.GetName(typeof(PublishStatusses), value)
}
Run Code Online (Sandbox Code Playgroud)
编辑:对于用户友好的字符串,您需要通过.resource来完成国际化/本地化,并且使用基于枚举键的固定键而不是相同的装饰器属性可能更好.
bjr*_*son 21
我创建了一个反向扩展方法,将描述转换回枚举值:
public static T ToEnumValue<T>(this string enumerationDescription) where T : struct
{
var type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("ToEnumValue<T>(): Must be of enum type", "T");
foreach (object val in System.Enum.GetValues(type))
if (val.GetDescription<T>() == enumerationDescription)
return (T)val;
throw new ArgumentException("ToEnumValue<T>(): Invalid description for enum " + type.Name, "enumerationDescription");
}
Run Code Online (Sandbox Code Playgroud)
Nol*_*rin 17
这里最简单的解决方案是使用自定义扩展方法(至少在.NET 3.5中 - 您可以将其转换为早期框架版本的静态帮助方法).
public static string ToCustomString(this PublishStatusses value)
{
switch(value)
{
// Return string depending on value.
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我在这里假设您想要返回除枚举值的实际名称之外的其他内容(您可以通过简单地调用ToString获得).
Lem*_*mmy 12
另一篇文章是Java.您不能在C#中将方法放在枚举中.
做这样的事情:
PublishStatusses status = ...
String s = status.ToString();
Run Code Online (Sandbox Code Playgroud)
如果要为枚举值使用不同的显示值,可以使用"属性"和"反射".
最简单的方法就是将此扩展类包含在项目中,它将与项目中的任何枚举一起使用:
public static class EnumExtensions
{
public static string ToFriendlyString(this Enum code)
{
return Enum.GetName(code.GetType(), code);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
enum ExampleEnum
{
Demo = 0,
Test = 1,
Live = 2
}
Run Code Online (Sandbox Code Playgroud)
...
ExampleEnum ee = ExampleEnum.Live;
Console.WriteLine(ee.ToFriendlyString());
Run Code Online (Sandbox Code Playgroud)
一些其他更原始的选项可以避免类/引用类型:
数组方法
private struct PublishStatusses
{
public static string[] Desc = {
"Not Completed",
"Completed",
"Error"
};
public enum Id
{
NotCompleted = 0,
Completed,
Error
};
}
Run Code Online (Sandbox Code Playgroud)
用法
string desc = PublishStatusses.Desc[(int)PublishStatusses.Id.Completed];
Run Code Online (Sandbox Code Playgroud)
嵌套的struct方法
private struct PublishStatusses
{
public struct NotCompleted
{
public const int Id = 0;
public const string Desc = "Not Completed";
}
public struct Completed
{
public const int Id = 1;
public const string Desc = "Completed";
}
public struct Error
{
public const int Id = 2;
public const string Desc = "Error";
}
}
Run Code Online (Sandbox Code Playgroud)
用法
int id = PublishStatusses.NotCompleted.Id;
string desc = PublishStatusses.NotCompleted.Desc;
Run Code Online (Sandbox Code Playgroud)
更新(03/09/2018)
扩展方法与上述第一种技术的混合.
我更喜欢将枚举定义为"属于"(最接近其原始来源而不是某些常见的全局命名空间).
namespace ViewModels
{
public class RecordVM
{
//public enum Enum { Minutes, Hours }
public struct Enum
{
public enum Id { Minutes, Hours }
public static string[] Name = { "Minute(s)", "Hour(s)" };
}
}
}
Run Code Online (Sandbox Code Playgroud)
扩展方法似乎适用于公共区域,枚举的"本地化"定义现在使扩展方法更加冗长.
namespace Common
{
public static class EnumExtensions
{
public static string Name(this RecordVM.Enum.Id id)
{
return RecordVM.Enum.Name[(int)id];
}
}
}
Run Code Online (Sandbox Code Playgroud)
枚举的用法示例及其扩展方法.
namespace Views
{
public class RecordView
{
private RecordDataFieldList<string, string> _fieldUnit;
public RecordView()
{
_fieldUnit.List = new IdValueList<string, string>
{
new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
};
}
private void Update()
{
RecordVM.Enum.Id eId = DetermineUnit();
_fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:我实际上决定消除Enum
包装器(和Name
数组),因为名称字符串最好来自资源(即配置文件或数据库)而不是硬编码,因为我最终将扩展方法放在ViewModels
命名空间(只是在另一个"CommonVM.cs"文件中).此外,整个.Id
事情变得分散注意力和繁琐.
namespace ViewModels
{
public class RecordVM
{
public enum Enum { Minutes, Hours }
//public struct Enum
//{
// public enum Id { Minutes, Hours }
// public static string[] Name = { "Minute(s)", "Hour(s)" };
//}
}
}
Run Code Online (Sandbox Code Playgroud)
CommonVM.cs
//namespace Common
namespace ViewModels
{
public static class EnumExtensions
{
public static string Name(this RecordVM.Enum id)
{
//return RecordVM.Enum.Name[(int)id];
switch (id)
{
case RecordVM.Enum.Minutes: return "Minute(s)";
case RecordVM.Enum.Hours: return "Hour(s)";
default: return null;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
枚举的用法示例及其扩展方法.
namespace Views
{
public class RecordView
{
private RecordDataFieldList<string, string> _fieldUnit
public RecordView()
{
_fieldUnit.List = new IdValueList<string, string>
{
new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
};
}
private void Update()
{
RecordVM.Enum eId = DetermineUnit();
_fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用Humanizer包和Humanize Enums possiblity.一个例子:
enum PublishStatusses
{
[Description("Custom description")]
NotCompleted,
AlmostCompleted,
Error
};
Run Code Online (Sandbox Code Playgroud)
那么你可以Humanize
直接在枚举上使用扩展方法:
var st1 = PublishStatusses.NotCompleted;
var str1 = st1.Humanize(); // will result in Custom description
var st2 = PublishStatusses.AlmostCompleted;
var str2 = st2.Humanize(); // will result in Almost completed (calculated automaticaly)
Run Code Online (Sandbox Code Playgroud)
使用静态类代替枚举。
代替
private enum PublishStatuses{
NotCompleted,
Completed,
Error
};
Run Code Online (Sandbox Code Playgroud)
和
private static class PublishStatuses{
public static readonly string NotCompleted = "Not Completed";
public static readonly string Completed = "Completed";
public static readonly string Error = "Error";
};
Run Code Online (Sandbox Code Playgroud)
它将像这样使用
PublishStatuses.NotCompleted; // "Not Completed"
Run Code Online (Sandbox Code Playgroud)
使用顶级“扩展方法”解决方案时出现的问题:
私有枚举经常在另一个类中使用。扩展方法解决方案在那里无效,因为它必须位于它自己的类中。该解决方案可以是私有的并嵌入到另一个类中。
小智 5
关于Ray Booysen,代码中存在一个错误:使用用户友好字符串的Enum ToString
您需要在枚举值上考虑多个属性.
public static string GetDescription<T>(this object enumerationValue)
where T : struct
{
Type type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
//Tries to find a DescriptionAttribute for a potential friendly name
//for the enum
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0 && attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault() != null)
{
//Pull out the description value
return ((DescriptionAttribute)attrs.Where(t=>t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()).Description;
}
}
//If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString();
Run Code Online (Sandbox Code Playgroud)
小智 5
public enum MyEnum
{
[Description("Option One")]
Option_One
}
public static string ToDescriptionString(this Enum This)
{
Type type = This.GetType();
string name = Enum.GetName(type, This);
MemberInfo member = type.GetMembers()
.Where(w => w.Name == name)
.FirstOrDefault();
DescriptionAttribute attribute = member != null
? member.GetCustomAttributes(true)
.Where(w => w.GetType() == typeof(DescriptionAttribute))
.FirstOrDefault() as DescriptionAttribute
: null;
return attribute != null ? attribute.Description : name;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
241855 次 |
最近记录: |