【发布时间】:2009-10-16 17:48:30
【问题描述】:
我想要一个枚举,如下所示:
enum FilterType
{
Rigid = "Rigid",
SoftGlow = "Soft / Glow",
Ghost = "Ghost",
}
如何做到这一点?有一个更好的方法吗?它将用于将被序列化/反序列化的对象的实例。它还将填充一个下拉列表。
【问题讨论】:
我想要一个枚举,如下所示:
enum FilterType
{
Rigid = "Rigid",
SoftGlow = "Soft / Glow",
Ghost = "Ghost",
}
如何做到这一点?有一个更好的方法吗?它将用于将被序列化/反序列化的对象的实例。它还将填充一个下拉列表。
【问题讨论】:
using System.ComponentModel;
enum FilterType
{
[Description("Rigid")]
Rigid,
[Description("Soft / Glow")]
SoftGlow,
[Description("Ghost")]
Ghost ,
}
你可以这样获取价值
public static String GetEnumerationDescription(Enum e)
{
Type type = e.GetType();
FieldInfo fieldInfo = type.GetField(e.ToString());
DescriptionAttribute[] da = (DescriptionAttribute[])(fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false));
if (da.Length > 0)
{
return da[0].Description;
}
return e.ToString();
}
【讨论】:
不,但是如果您想限定“const”字符串的范围并像枚举一样使用它们,这就是我所做的:
public static class FilterType
{
public const string Rigid = "Rigid";
public const string SoftGlow = "Soft / Glow";
public const string Ghost ="Ghost";
}
【讨论】:
如果您对扩展方法感到满意,您可以轻松地做您想做的事情:
//Can return string constants, the results of a Database call,
//or anything else you need to do to get the correct value
//(for localization, for example)
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!!";
}
这样你就可以做到:
Private MyEnum value = MyEnum.First;
Console.WriteLine(value.EnumValue());
【讨论】:
不,但你可以这样作弊:
public enum FilterType{
Rigid,
SoftGlow,
Ghost
}
然后,当您需要他们的字符串值时,您可以执行FilterType.Rigid.ToString()。
【讨论】:
枚举总是链接到一个整数值。所以不行。 可以通过FilterType.Rigid.ToString()获取字符串值,虽然不能直接本地化。
【讨论】:
您可以像这样将枚举名称作为字符串获取
FilterType myType = FilterType.Rigid;
String strType = myType.ToString();
但是,您可能会被 Camel Case/Hungarian 表示法困住,但您可以使用这样的方法轻松地将其转换为对用户更友好的字符串(不是最漂亮的解决方案,我将不胜感激有关优化此的输入) :
Public Shared Function NormalizeCamelCase(ByVal str As String) As String
If String.IsNullOrEmpty(str) Then
Return String.Empty
End If
Dim i As Integer = 0
Dim upperCount As Integer = 0
Dim otherCount As Integer = 0
Dim normalizedString As String = str
While i < normalizedString.Length
If Char.IsUpper(normalizedString, i) Then
''Current char is Upper Case
upperCount += 1
If i > 0 AndAlso Not normalizedString(i - 1).Equals(" "c) Then
''Current char is not first and preceding char is not a space
''...insert a space, move to next char
normalizedString = normalizedString.Insert(i, " ")
i += 1
End If
ElseIf Not Char.IsLetter(normalizedString, i) Then
otherCount += 1
End If
''Move to next char
i += 1
End While
If upperCount + otherCount = str.Length Then
''String is in all caps, return original string
Return str
Else
Return normalizedString
End If
End Function
如果这还不够漂亮,您可能需要查看自定义属性,可以使用反射检索...
【讨论】:
在 System.ComponentModel 命名空间中有一个类 DescriptionAttribute 在这里工作得很好。
enum FilterType
{
Rigid,
[Description("Soft / Glow")]
SoftGlow,
Ghost,
}
然后获取描述并故障转移到 ToString()
var descriptionAttribute = Value.GetType()
.GetField(Value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.OfType <DescriptionAttribute>()
.FirstOrDefault()??new DescriptionAttribute(Value.ToString());
【讨论】:
这是不可能的。 C# 只允许整数枚举类型(int、short、long 等)。您可以创建一个轻量级的“类枚举”类或使用静态常量。
static class FilterTypes
{
public const string Rigid = "Rigid";
// ...
}
// or ...
class FilterType
{
static readonly FilterType RigidFilterType = new FilterType("Rigid");
string name;
FilterType(string name) // private constructor
{
this.name = name;
}
public static FilterType Rigid
{
get { return FilterType.RigidFilterType; }
}
// ...
}
【讨论】:
这不是完全可能的。但是,您可以使用数组来伪造它。
首先,以常规方式创建枚举:
public enum Regexs
{
ALPHA = 0,
NUMERIC = 1,
etc..
}
然后你创建一个数组来保存与枚举值对应的值:
private static string[] regexs = new string[]
{
"[A-Za-z]",
"[0-9]",
"etc"...
}
然后你可以通过枚举值访问你的字符串:
public void runit(Regexs myregexEnum)
{
Regex regex = new Regex( regexs [(int)myregexEnum] );
}
【讨论】:
不,这是不可能的。
枚举的批准类型是 字节,sbyte,短,ushort,int,uint, long 或 ulong。
但是,您可以使用 Enum 类检索声明的枚举名称:
string name = Enum.GetName(typeof(FilterType), FilterType.Rigid);
如果这对您不起作用,则可能是在一个类中收集的字符串常量集合。
【讨论】:
您可以在值上使用属性
[System.ComponentModel.Description("Rigid")]
示例:
enum FilterType
{
[System.ComponentModel.Description("Rigid")]
Rigid,
[System.ComponentModel.Description("Soft / Glow")]
SoftGlow,
[System.ComponentModel.Description("Ghost")]
Ghost
}
并使用反射来获取描述。
枚举扩展方法:
public static string GetDescription(this Enum en)
{
var type = en.GetType();
var memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
return ((DescriptionAttribute)attrs[0]).Description;
}
return en.ToString();
}
使用它:
FilterType = FilterType.Rigid;
string description= result.GetDescription();
【讨论】:
按照 Shaun Bowe 的示例,您也可以在 C# 3 中使用 enum 的扩展方法执行此操作(我没有想出,也无法记住我在哪里做的)。
创建一个属性:
public class DisplayTextAttribute : Attribute {
public DisplayTextAttribute(String text) {
Text = text;
}
public string Text { get; set; }
}
创建一个扩展:
public static class EnumHelpers {
public static string GetDisplayText(this Enum enumValue) {
var type = enumValue.GetType();
MemberInfo[] memberInfo = type.GetMember(enumValue.ToString());
if (memberInfo == null || memberInfo.Length == 0)
return enumValue.ToString();
object[] attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayTextAttribute), false);
if (attributes == null || attributes.Length == 0)
return enumValue.ToString();
return ((DisplayTextAttribute)attributes[0]).Text;
}
}
我发现这是一个非常整洁的解决方案。 在您的枚举中添加以下内容:
enum FilterType{
Rigid,
[DisplayText("Soft / Glow")]
SoftGlow,
Ghost
}
然后您可以访问FilterType.GetDisplayText(),它将为未归属的枚举拉回字符串,为具有属性的枚举拉回 displayText。
【讨论】: