无法从其StringValue属性解析为枚举对象。
枚举:
public enum StatusColor
{
[StringValue("#FFFFFF")]
None,
[StringValue("#5DB516")]
Green,
[StringValue("#F3212A")]
Red,
[StringValue("#FFFFFF")]
White
}
解析尝试1
string inputHtmlColor = "#F3212A"; // input
StatusColor outColor; // output
Enum.TryParse(inputHtmlColor , true, out outColor);
解析尝试2:
string inputHtmlColor = "#F3212A"; //input
StatusColor outColor = Enum.Parse(typeof(StatusColor), inputHtmlColor, true);
两个代码都不起作用,代码始终选择StausColor.None
(第一个)。如何获得正确的StatusColor
枚举对象?
答案 0 :(得分:2)
这应该做到:
public StatusColor GetColor(string color)
{
return
Enum.GetValues(typeof(StatusColor))
.Cast<StatusColor>()
.First(x => ((StringValueAttribute)typeof(StatusColor)
.GetField(x.ToString())
.GetCustomAttribute(typeof(StringValueAttribute))).Value == color);
}
答案 1 :(得分:1)
我将创建一个反向查询字典,该字典采用枚举值并返回匹配的枚举值:
public static void main(String[] args) {
int input[] = {1, 3, 9, 6, 5, 8, 3, 4};
Map<Integer, Integer> valueMap = new HashMap<>();
for (int i = 0; i < input.length - 1; i++) {
for (int j = i + 1; j < input.length; j++) {
if (9 - input[i] == input[j]) {
if((valueMap.containsKey(input[i])&&valueMap.containsValue(input[j])) || (valueMap.containsKey(input[j])&&valueMap.containsValue(input[i]))) {
//these are repetitive values
} else {
valueMap.put(input[i], input[j]);
System.out.println("[" + input[i] + ", " + input[j] + "]");
}
}
}
}
}
我已使此方法尽可能通用,以便可以应用于许多用例。您的情况下的用法如下所示:
public static IDictionary<TKey, TEnum> GetReverseEnumLookup<TEnum, TKey, TAttribute>(Func<TAttribute, TKey> selector, IEqualityComparer<TKey> comparer = null)
where TEnum: struct, IConvertible // pre-C#7.3
// where TEnum : System.Enum // C#7.3+
where TAttribute: System.Attribute
{
// use the default comparer for the dictionary if none is specified
comparer = comparer ?? EqualityComparer<TKey>.Default;
// construct a lookup dictionary with the supplied comparer
Dictionary<TKey, TEnum> values = new Dictionary<TKey, TEnum>(comparer);
// get all of the enum values
Type enumType = typeof(TEnum);
var enumValues = typeof(TEnum).GetEnumValues().OfType<TEnum>();
// for each enum value, get the corresponding field member from the enum
foreach (var val in enumValues)
{
var member = enumType.GetMember(val.ToString()).First();
// if there is an attribute, save the selected value and corresponding enum value in the dictionary
var attr = member.GetCustomAttribute<TAttribute>();
if (attr != null)
{
values[selector(attr)] = val;
}
}
return values;
}
然后您可以将查找静态地存储在某个地方,并且查找值如下:
var lookup = GetReverseEnumLookup<StatusColor, string, StringValueAttribute>(v => v.Value, StringComparer.OrdinalIgnoreCase); // I figure you want this to be case insensitive
答案 2 :(得分:1)
您的呼叫代码:
string inputHtmlColor = "#F3212A";
StatusColor outColor = inputHtmlColor.GetEnumFromString<StatusColor>();
这就是调用以下扩展方法的方式。
public static class EnumEx
{
public static T GetEnumFromString<T>(this string stringValue)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(StringValueAttribute)) as StringValueAttribute;
if (attribute != null)
{
if (attribute.Value == stringValue)
return (T)field.GetValue(null);
}
else
{
if (field.Name == stringValue)
return (T)field.GetValue(null);
}
}
throw new ArgumentException("Not found.", "stringValue");
// or return default(T);
}
}
关于属性的注释:
我这样定义我的属性:
public class StringValueAttribute : Attribute
{
public string Value { get; private set; }
public StringValueAttribute(string value)
{
Value = value;
}
}
如果您的StringValueAttribute
的定义不同,请随时更新您的问题以包括该类型定义,并且如有必要,我将更新我的答案。
答案 3 :(得分:0)
我为此创建了一种方法
StringEnum.GetStringValue(Pass Your enum here)
调用在普通类中创建的函数
public static string GetStringValue(Enum value)
{
string output = null;
try
{
Type type = value.GetType();
if (_stringValues.ContainsKey(value))
output = (_stringValues[value] as StringValueAttribute).Value;
else
{
////Look for our 'StringValueAttribute' in the field's custom attributes
FieldInfo fi = type.GetField(value.ToString());
StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
if (attrs.Length > 0)
{
_stringValues.Add(value, attrs[0]);
output = attrs[0].Value;
}
}
}
catch (Exception)
{
}
return output;
}
答案 4 :(得分:0)
只需最小的更改即可完成工作:
实用程序类:
private static IDictionary<string, StatusColor> _statusColorByHtml = Enum.GetValues(typeof(StatusColor)).Cast<StatusColor>().ToDictionary(k => k.GetStringValue(), v => v);
public static StatusColor GetStatusColor(string htmlColor)
{
_statusColorByHtml.TryGetValue(htmlColor, out StatusColor color);
return color;
}