我有以下列举:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
然而问题是,当我请求AuthenticationMethod时,我需要“FORMS”这个词。表单而不是id
对于这个问题,我找到了以下解决方案(链接):
首先,我需要创建一个自定义属性“StringValue”:
public class StringValue : System.Attribute
{
private readonly string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
然后我可以将这个属性添加到我的枚举器中:
public enum AuthenticationMethod
{
[StringValue("FORMS")]
FORMS = 1,
[StringValue("WINDOWS")]
WINDOWSAUTHENTICATION = 2,
[StringValue("SSO")]
SINGLESIGNON = 3
}
当然,我需要一些东西来检索StringValue:
public static class StringEnum
{
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
//Check first in our cached results...
//Look for our 'StringValueAttribute'
//in the field's custom attributes
FieldInfo fi = type.GetField(value.ToString());
StringValue[] attrs =
fi.GetCustomAttributes(typeof(StringValue),
false) as StringValue[];
if (attrs.Length > 0)
{
output = attrs[0].Value;
}
return output;
}
}
很好,现在我已经有了工具来获取枚举器的字符串值。
然后我可以这样使用它:
string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);
好的,现在所有这些工作就像一个魅力,但我发现它有很多工作。我想知道有没有更好的解决办法。
我还尝试了一些字典和静态属性,但这也不是更好。
我支持Harvey,但不用const。我可以混合匹配字符串,int,等等。
public class xlsLayout
{
public int xlHeaderRow = 1;
public int xlFirstDataRow = 2;
public int xlSkipLinesBetweenFiles = 1; //so 0 would mean don't skip
public string xlFileColumn = "A";
public string xlFieldColumn = "B";
public string xlFreindlyNameColumn = "C";
public string xlHelpTextColumn = "D";
}
然后……
public partial class Form1 : Form
{
xlsLayout xlLayout = new xlsLayout();
xl.SetCell(xlLayout.xlFileColumn, xlLayout.xlHeaderRow, "File Name");
xl.SetCell(xlLayout.xlFieldColumn, xlLayout.xlHeaderRow, "Code field name");
xl.SetCell(xlLayout.xlFreindlyNameColumn, xlLayout.xlHeaderRow, "Freindly name");
xl.SetCell(xlLayout.xlHelpTextColumn, xlLayout.xlHeaderRow, "Inline Help Text");
}
我的答案是,正在处理@user29964的答案(这是迄今为止最简单和最接近Enum的答案)
public class StringValue : System.Attribute
{
private string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
public static string GetStringValue(Enum Flagvalue)
{
Type type = Flagvalue.GetType();
string[] flags = Flagvalue.ToString().Split(',').Select(x => x.Trim()).ToArray();
List<string> values = new List<string>();
for (int i = 0; i < flags.Length; i++)
{
FieldInfo fi = type.GetField(flags[i].ToString());
StringValue[] attrs =
fi.GetCustomAttributes(typeof(StringValue),
false) as StringValue[];
if (attrs.Length > 0)
{
values.Add(attrs[0].Value);
}
}
return String.Join(",", values);
}
使用
[Flags]
public enum CompeteMetric
{
/// <summary>
/// u
/// </summary>
[StringValue("u")]//Json mapping
Basic_UniqueVisitors = 1 //Basic
,
/// <summary>
/// vi
/// </summary>
[StringValue("vi")]//json mapping
Basic_Visits = 2// Basic
,
/// <summary>
/// rank
/// </summary>
[StringValue("rank")]//json mapping
Basic_Rank = 4//Basic
}
例子
CompeteMetric metrics = CompeteMetric.Basic_Visits | CompeteMetric.Basic_Rank;
string strmetrics = StringValue.GetStringValue(metrics);
它会返回
“vi,排名”
我的变体
public struct Colors
{
private String current;
private static string red = "#ff0000";
private static string green = "#00ff00";
private static string blue = "#0000ff";
private static IList<String> possibleColors;
public static Colors Red { get { return (Colors) red; } }
public static Colors Green { get { return (Colors) green; } }
public static Colors Blue { get { return (Colors) blue; } }
static Colors()
{
possibleColors = new List<string>() {red, green, blue};
}
public static explicit operator String(Colors value)
{
return value.current;
}
public static explicit operator Colors(String value)
{
if (!possibleColors.Contains(value))
{
throw new InvalidCastException();
}
Colors color = new Colors();
color.current = value;
return color;
}
public static bool operator ==(Colors left, Colors right)
{
return left.current == right.current;
}
public static bool operator !=(Colors left, Colors right)
{
return left.current != right.current;
}
public bool Equals(Colors other)
{
return Equals(other.current, current);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (obj.GetType() != typeof(Colors)) return false;
return Equals((Colors)obj);
}
public override int GetHashCode()
{
return (current != null ? current.GetHashCode() : 0);
}
public override string ToString()
{
return current;
}
}
代码看起来有点丑,但是这个结构体的用法很有代表性。
Colors color1 = Colors.Red;
Console.WriteLine(color1); // #ff0000
Colors color2 = (Colors) "#00ff00";
Console.WriteLine(color2); // #00ff00
// Colors color3 = "#0000ff"; // Compilation error
// String color4 = Colors.Red; // Compilation error
Colors color5 = (Colors)"#ff0000";
Console.WriteLine(color1 == color5); // True
Colors color6 = (Colors)"#00ff00";
Console.WriteLine(color1 == color6); // False
此外,我认为,如果需要大量这样的枚举,可能会使用代码生成(例如T4)。
我使用系统中的Description属性。ComponentModel名称空间。简单地装饰枚举,然后使用下面的代码来检索它:
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)
{
//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();
}
举个例子:
public enum Cycle : int
{
[Description("Daily Cycle")]
Daily = 1,
Weekly,
Monthly
}
这段代码很好地满足了不需要“友好名称”的枚举,只返回枚举的. tostring()。