Sun*_*nny 17 .net json.net .net-3.5
我已经TryParse
通过值或名称编写了枚举代码,如下所示.如何扩展此代码以包含使用Flags
属性解析枚举?
public static bool TryParse<T>(this T enum_type, object value, out T result)
where T : struct
{
return enum_type.TryParse<T>(value, true, out result);
}
public static bool TryParse<T>(this T enum_type,
object value, bool ignoreCase, out T result)
where T : struct
{
result = default(T);
var is_converted = false;
var is_valid_value_for_conversion = new Func<T, object, bool, bool>[]{
(e, v, i) => e.GetType().IsEnum,
(e, v, i) => v != null,
(e, v, i) => Enum.GetNames(e.GetType()).Any(n => String.Compare(n, v.ToString(), i) == 0) || Enum.IsDefined(e.GetType(), v)
};
if(is_valid_value_for_conversion.All(rule => rule(enum_type, value, ignoreCase))){
result = (T)Enum.Parse(typeof(T), value.ToString(), ignoreCase);
is_converted = true;
}
return is_converted;
}
Run Code Online (Sandbox Code Playgroud)
目前此代码适用于以下枚举:
enum SomeEnum{ A, B, C }
// can parse either by 'A' or 'a'
enum SomeEnum1 : int { A = 1, B = 2, C = 3 }
// can parse either by 'A' or 'a' or 1 or "1"
Run Code Online (Sandbox Code Playgroud)
不起作用:
[Flags]
enum SomeEnum2 { A = 1, B = 2, C = 4 } // can parse either by 'A' or 'a'
// cannot parse for A|B
Run Code Online (Sandbox Code Playgroud)
谢谢!
Pop*_*lin 33
标志枚举是使用,
.Net约定而不是使用|
.使用','字符串时,Enum.Parse()可以正常工作:
[Flags]
public enum Flags
{
A = 1,
B = 2,
C = 4,
D = 8,
}
var enumString = (Flags.A | Flags.B | Flags.C).ToString();
Console.WriteLine(enumString); // Outputs: A, B, C
Flags f = (Flags)Enum.Parse(typeof(Flags), enumString);
Console.WriteLine(f); // Outputs: A, B, C
Run Code Online (Sandbox Code Playgroud)
dtb*_*dtb 17
从.NET 4开始,有一个Enum.TryParse <T>方法.它支持开箱即用的Flags枚举:
string x = (SomeEnum2.A | SomeEnum2.B).ToString(); // x == "A, B"
SomeEnum2 y;
bool success = Enum.TryParse<SomeEnum2>(x, out y); // y == A|B
Run Code Online (Sandbox Code Playgroud)
@Pop 的回答给了我一个线索,我修改了代码中的规则检查,如下所示:
var is_valid_value_for_conversion = new Func<T, object, bool, bool>[]
{
(e, v, i) => e.GetType().IsEnum,
(e, v, i) => value != null,
(e, v, i) => Enum.GetNames(e.GetType()).Any(
n => String.Compare(n, v.ToString(), i) == 0
|| (v.ToString().Contains(",") && v.ToString().ToLower().Contains(n.ToLower())))
|| Enum.IsDefined(e.GetType(), v)
};
Run Code Online (Sandbox Code Playgroud)
其余部分保持不变,这对我有用
HTH 别人