我希望有一个类似下面的枚举,然后有一个类似于Util.FindFruitByValue(“A”)的方法返回枚举Apple。这是因为缩写存储在数据库中,我需要在从db读取后将它们转换为适当的枚举。这是可能的还是我需要为它创建一个单独的类?请告诉我。提前谢谢。
public enum Fruit
{
Apple = "A"
Banana = "B"
Cherry = "C"
}
更新:这就像一个查找表,但区别在于值是字符串而不是int。我通过从数据库中读取值来填充业务对象,我想使用具有固定值的类型而不是字符串。
答案 0 :(得分:20)
我通过在枚举上使用Description属性解决了这个问题。解决方案如下。我使用扩展方法来获取描述。获取描述的代码来自此链接http://blog.spontaneouspublicity.com/post/2008/01/17/Associating-Strings-with-enums-in-C.aspx。谢谢你的回复。
public enum Fruit
{
[Description("Apple")]
A,
[Description("Banana")]
B,
[Description("Cherry")]
C
}
public static class Util
{
public static T StringToEnum<T>(string name)
{
return (T)Enum.Parse(typeof(T), name);
}
public static string ToDescriptionString(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
答案 1 :(得分:12)
您可以将值放在Dictionary
中以有效地查找它们:
Dictionary<string, Fruit> fruitValues = new Dictionary<string, Fruit>();
fruitValues.Add("A", Fruit.Apple);
fruitValues.Add("B", Fruit.Banana);
fruitValues.Add("C", Fruit.Cherry);
查找
string dataName = "A";
Fruit f = fruitValues[dataName];
如果该值可能不存在:
string dataName = "A";
Fruit f;
if (fruitValues.TryGetValue(dataName, out f)) {
// got the value
} else {
// there is no value for that string
}
答案 2 :(得分:2)
我写了一个库来处理这个问题。它本来只是为了反过来(从和Enum返回一个字符串值),但是一旦我写了,能够将一个字符串解析回它的Enum,只是一小步。
该库名为EnumStringValues,可从VS中的nuget获得(包页也在这里:https://www.nuget.org/packages/EnumStringValues) SourceCode在GitHub上:https://github.com/Brondahl/EnumStringValues
欢迎提出想法和意见。 灵感显然来自于其他答案中引用的广为人知的属性方法。
答案 3 :(得分:1)
如何使用Hashtable?
答案 4 :(得分:1)
对不起,我忽略了OP的Enum的定义。 显然,Enum值必须是数字类型,因此OP的定义不起作用。
我想到的是将char值用作Enum值,例如:
public enum Fruit
{
Apple = 65, //"A",
Banana = 66, // "B",
Cherry = 67 //"C"
}
根据Convert.ToInt32('A') - 不知道如何处理区分大小写。 然后,通过强制转换获取正确的结果。我还在玩一个例子,很高兴听到一些建议。
好的,抱歉延误了。以下是对此的更多信息:
public static class EnumConverter<T>
{
public static T ToEnum(char charToConvert, out bool success)
{
try
{
int intValue = Convert.ToInt32(charToConvert);
if (Enum.IsDefined(typeof(T), intValue))
{
success = true;
return (T)Enum.ToObject(typeof(T), intValue);
}
}
catch (ArgumentException ex)
{
// Use your own Exception Management Here
}
catch (InvalidCastException ex)
{
// Use your own Exception Management Here
}
success = false;
return default(T);
}
}
用法:
bool success = false;
Fruit selected = EnumConverter<Fruit>.ToEnum('A', out success);
if (success)
{
// go for broke
}
答案 5 :(得分:0)
我制作了一个小的DynamicEnum类,可以很容易地将枚举进出域和数据存储库。
public abstract class DynamicEnum<T> : IEquatable<T>, IComparable<T>
where T : DynamicEnum<T>, new()
{
#region Instance
public int PathCode { get; private set; }
public string PathValue { get; private set; }
protected DynamicEnum() { }
protected DynamicEnum(int pathCode, string pathValue)
{
PathCode = pathCode;
PathValue = PathValue;
}
#region IEquatable<AreaStatus> Members
public bool Equals(T other)
{
return PathCode == other.PathCode;
}
#endregion
public override bool Equals(object obj)
{
return Equals(obj as T);
}
public override int GetHashCode()
{
return PathCode.GetHashCode();
}
#region IComparable<AreaStatus> Members
public int CompareTo(T other)
{
return PathCode.CompareTo(other.PathCode);
}
#endregion
#endregion
#region Class / Static
static DynamicEnum()
{
// Despite appearances, static methods are not really inherited by
// child classes. This means when the mapping fields below are accessed
// by an implementing class the CLR does not see it as a method on that
// class. In the event that the implementing class's static constructor
// hasn't been called yet, it will not be called at that point since
// technically no static method/property or instance of the implementing
// class has been used. Working around this by creating an instance here
// which causes the derived class's static constructor to be called
// beforehand. This could alternately be solved by moving the default 'enum'
// value initialization out of the implementing classes to the Global.asax
// where the database 'enum' values are optionally loaded.
new T();
}
public static void Initialize(IEnumerable<T> statuses)
{
IntoDomainMapping = statuses.ToDictionary(x => x.PathValue, x => x);
IntoDBMapping = IntoDomainMapping.ToDictionary(x => x.Value, x => x.Key);
}
public static Dictionary<string, T> IntoDomainMapping { get; protected set; }
public static Dictionary<T, string> IntoDBMapping { get; protected set; }
#endregion
#region Operator Overloads
public static bool operator ==(DynamicEnum<T> s1, T s2)
{
return s1.Equals(s2);
}
public static bool operator !=(DynamicEnum<T> s1, T s2)
{
return !s1.Equals(s2);
}
public static bool operator >(DynamicEnum<T> s1, T s2)
{
return s1.CompareTo(s2) > 0;
}
public static bool operator <(DynamicEnum<T> s1, T s2)
{
return s1.CompareTo(s2) < 0;
}
public static bool operator >=(DynamicEnum<T> s1, T s2)
{
return s1.CompareTo(s2) >= 0;
}
public static bool operator <=(DynamicEnum<T> s1, T s2)
{
return s1.CompareTo(s2) <= 0;
}
#endregion
}
这是“Enum”类
public class ResourcePath : DynamicEnum<ResourcePath>
{
public ResourcePath() { }
public ResourcePath(int pathCode, string pathValue)
: base(pathCode, pathValue) { }
static ResourcePath()
{
Initialize(new List<ResourcePath>
{
new ResourcePath(1, "customer.list"),
new ResourcePath(1, "customer.create"),
new ResourcePath(1, "customer.info"),
new ResourcePath(1, "customer.update"),
new ResourcePath(1, "customer.delete"),
});
}
public static ResourcePath Deleted
{
get { return ResourcePath.IntoDomainMapping["DE"]};
}
}
最后基本用法
var resource = GetAllResources().Where(e => e.PathCode == pathCode).firstOrDefault();
答案 6 :(得分:0)