我的枚举由以下值组成:
private enum PublishStatusses{
NotCompleted,
Completed,
Error
};
我希望能够以用户友好的方式输出这些值。 我不需要再从字符串到值。
我的枚举由以下值组成:
private enum PublishStatusses{
NotCompleted,
Completed,
Error
};
我希望能够以用户友好的方式输出这些值。 我不需要再从字符串到值。
当前回答
另一篇文章是Java。在c#中,你不能把方法放在枚举中。
就像这样做:
PublishStatusses status = ...
String s = status.ToString();
如果您想为枚举值使用不同的显示值,您可以使用Attributes和Reflection。
其他回答
如果你想要完全可定制的东西,试试我的解决方案:
http://www.kevinwilliampang.com/post/Mapping-Enums-To-Strings-and-Strings-to-Enums-in-NET.aspx
基本上,这篇文章概述了如何将Description属性附加到每个枚举,并提供了从枚举映射到描述的通用方法。
不要使用枚举,使用静态类。
取代
private enum PublishStatuses{
NotCompleted,
Completed,
Error
};
with
private static class PublishStatuses{
public static readonly string NotCompleted = "Not Completed";
public static readonly string Completed = "Completed";
public static readonly string Error = "Error";
};
它是这样使用的
PublishStatuses.NotCompleted; // "Not Completed"
使用顶级“扩展方法”解决方案的问题:
私有枚举通常在另一个类中使用。扩展方法解决方案在那里无效,因为它必须在它自己的类中。这个解决方案可以是私有的,并嵌入到另一个类中。
其他一些避免类/引用类型的更基本的选项:
数组的方法 嵌套结构方法
数组的方法
private struct PublishStatusses
{
public static string[] Desc = {
"Not Completed",
"Completed",
"Error"
};
public enum Id
{
NotCompleted = 0,
Completed,
Error
};
}
使用
string desc = PublishStatusses.Desc[(int)PublishStatusses.Id.Completed];
嵌套结构方法
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";
}
}
使用
int id = PublishStatusses.NotCompleted.Id;
string desc = PublishStatusses.NotCompleted.Desc;
更新(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)" };
}
}
}
扩展方法似乎适合于公共区域,枚举的“本地化”定义现在使扩展方法更加详细。
namespace Common
{
public static class EnumExtensions
{
public static string Name(this RecordVM.Enum.Id id)
{
return RecordVM.Enum.Name[(int)id];
}
}
}
枚举及其扩展方法的使用示例。
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;
}
}
}
注意:我实际上决定消除Enum包装器(和Name数组),因为名称字符串最好来自资源(即配置文件或DB)而不是硬编码,并且因为我最终将扩展方法放在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)" };
//}
}
}
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;
}
}
}
}
枚举及其扩展方法的使用示例。
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;
}
}
}
用于标记枚举,包括。
public static string Description(this Enum value)
{
Type type = value.GetType();
List<string> res = new List<string>();
var arrValue = value.ToString().Split(',').Select(v=>v.Trim());
foreach (string strValue in arrValue)
{
MemberInfo[] memberInfo = type.GetMember(strValue);
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)
{
res.Add(((DescriptionAttribute)attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()).Description);
}
else
res.Add(strValue);
}
else
res.Add(strValue);
}
return res.Aggregate((s,v)=>s+", "+v);
}
这是对Ray Booysen的代码的更新,使用通用的GetCustomAttributes方法和LINQ使事情变得更整洁。
/// <summary>
/// Gets the value of the <see cref="T:System.ComponentModel.DescriptionAttribute"/> on an struct, including enums.
/// </summary>
/// <typeparam name="T">The type of the struct.</typeparam>
/// <param name="enumerationValue">A value of type <see cref="T:System.Enum"/></param>
/// <returns>If the struct has a Description attribute, this method returns the description. Otherwise it just calls ToString() on the struct.</returns>
/// <remarks>Based on http://stackoverflow.com/questions/479410/enum-tostring/479417#479417, but useful for any struct.</remarks>
public static string GetDescription<T>(this T enumerationValue) where T : struct
{
return enumerationValue.GetType().GetMember(enumerationValue.ToString())
.SelectMany(mi => mi.GetCustomAttributes<DescriptionAttribute>(false),
(mi, ca) => ca.Description)
.FirstOrDefault() ?? enumerationValue.ToString();
}