Enum.TryParse在.NET 3.5的实现 [英] Implementation of Enum.TryParse in .NET 3.5
本文介绍了Enum.TryParse在.NET 3.5的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我怎么能在.NET 3.5实现了.NET 4的Enum.TryParse方法?
公共静态布尔的TryParse< TEnum>(字符串值,出TEnum结果),其中TEnum:结构
解决方案
花费的时间比我希望能得到这个权利,但它的工作原理,并进行了测试。希望这样可以节省别人一些时间!
私有静态只读的char [] FlagDelimiter =新的[] {','};
公共静态布尔TryParseEnum< TEnum>(字符串值,出TEnum结果),其中TEnum:结构{
如果(string.IsNullOrEmpty(值)){
结果=默认(TEnum);
返回false;
}
VAR enumType = typeof运算(TEnum);
如果(!enumType.IsEnum)
抛出新的ArgumentException(的String.Format(类型{0}不是枚举,enumType.FullName));
结果=默认(TEnum);
//尝试直接解析值
如果(Enum.IsDefined(enumType,值)){
结果=(TEnum)Enum.Parse(enumType,价值);
返回true;
}
//获取在枚举一些信息
VAR enumValues = Enum.GetValues(enumType);
如果(enumValues.Length == 0)
返回false; //大概不能发生,因为你不能确定空枚举?
VAR enumType code = Type.GetType code(enumValues.GetValue(0).GetType());
//尝试解析它作为一个标志
如果(value.IndexOf(,)!= - 1){
如果(!Attribute.IsDefined(enumType的typeof(的FlagsAttribute)))
返回false; //值都有标志,但枚举是不是标志
// TODO:此缓存效率
VAR enumInfo =新字典<字符串,对象>();
VAR enumNames = Enum.GetNames(enumType);
对于(VAR I = 0; I< enumNames.Length;我++)
enumInfo.Add(enumNames [I],enumValues.GetValue(ⅰ));
ULONG retVal的= 0;
的foreach(在value.Split(FlagDelimiter VAR名)){
变种trimmedName = name.Trim();
如果(!enumInfo.ContainsKey(trimmedName))
返回false; //枚举没有这样的标志
VAR enumValueObject = enumInfo [trimmedName]
ULONG enumValueLong;
开关(enumType code){
案件类型code.Byte:
enumValueLong =(字节)enumValueObject;
打破;
案件类型code.SByte:
enumValueLong =(字节)((为sbyte)enumValueObject);
打破;
案件类型code.Int16:
enumValueLong =(USHORT)((短)enumValueObject);
打破;
案件类型code.Int32:
enumValueLong =(UINT)((INT)enumValueObject);
打破;
案件类型code.Int64:
enumValueLong =(ULONG)((长)enumValueObject);
打破;
案件类型code.UInt16:
enumValueLong =(USHORT)enumValueObject;
打破;
案件类型code.UInt32:
enumValueLong =(UINT)enumValueObject;
打破;
案件类型code.UInt64:
enumValueLong =(ULONG)enumValueObject;
打破;
默认:
返回false; //应该永远不会发生
}
retVal的| = enumValueLong;
}
结果=(TEnum)Enum.ToObject(enumType,retVal的);
返回true;
}
//值可以是一个数字,因此,直接分析它
开关(enumType code){
案件类型code.SByte:
为sbyte某人;
如果(!SByte.TryParse(值,出某人))
返回false;
结果=(TEnum)Enum.ToObject(enumType,某人);
打破;
案件类型code.Byte:
BYTE B;
如果(!Byte.TryParse(价值,OUT B))
返回false;
结果=(TEnum)Enum.ToObject(enumType,B);
打破;
案件类型code.Int16:
短I16;
如果(!Int16.TryParse(值,出I16))
返回false;
结果=(TEnum)Enum.ToObject(enumType,I16);
打破;
案件类型code.UInt16:
USHORT U16;
如果(!UInt16.TryParse(值,从U16))
返回false;
结果=(TEnum)Enum.ToObject(enumType,U16);
打破;
案件类型code.Int32:
INT I32;
如果(!Int32.TryParse(值,出I32))
返回false;
结果=(TEnum)Enum.ToObject(enumType,I32);
打破;
案件类型code.UInt32:
UINT U32;
如果(!UInt32.TryParse(值,从U32))
返回false;
结果=(TEnum)Enum.ToObject(enumType,U32);
打破;
案件类型code.Int64:
长I64;
如果(!Int64.TryParse(值,出I64))
返回false;
结果=(TEnum)Enum.ToObject(enumType,I64);
打破;
案件类型code.UInt64:
ULONG U64;
如果(!UInt64.TryParse(值,从U64))
返回false;
结果=(TEnum)Enum.ToObject(enumType,U64);
打破;
默认:
返回false; //应该永远不会发生
}
返回true;
}
How could I implement the .NET 4's Enum.TryParse method in .NET 3.5?
public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct
解决方案
Took longer than I hoped to get this right, but it works and has been tested. Hope this saves someone some time!
private static readonly char[] FlagDelimiter = new [] { ',' };
public static bool TryParseEnum<TEnum>(string value, out TEnum result) where TEnum : struct {
if (string.IsNullOrEmpty(value)) {
result = default(TEnum);
return false;
}
var enumType = typeof(TEnum);
if (!enumType.IsEnum)
throw new ArgumentException(string.Format("Type '{0}' is not an enum", enumType.FullName));
result = default(TEnum);
// Try to parse the value directly
if (Enum.IsDefined(enumType, value)) {
result = (TEnum)Enum.Parse(enumType, value);
return true;
}
// Get some info on enum
var enumValues = Enum.GetValues(enumType);
if (enumValues.Length == 0)
return false; // probably can't happen as you cant define empty enum?
var enumTypeCode = Type.GetTypeCode(enumValues.GetValue(0).GetType());
// Try to parse it as a flag
if (value.IndexOf(',') != -1) {
if (!Attribute.IsDefined(enumType, typeof(FlagsAttribute)))
return false; // value has flags but enum is not flags
// todo: cache this for efficiency
var enumInfo = new Dictionary<string, object>();
var enumNames = Enum.GetNames(enumType);
for (var i = 0; i < enumNames.Length; i++)
enumInfo.Add(enumNames[i], enumValues.GetValue(i));
ulong retVal = 0;
foreach(var name in value.Split(FlagDelimiter)) {
var trimmedName = name.Trim();
if (!enumInfo.ContainsKey(trimmedName))
return false; // Enum has no such flag
var enumValueObject = enumInfo[trimmedName];
ulong enumValueLong;
switch (enumTypeCode) {
case TypeCode.Byte:
enumValueLong = (byte)enumValueObject;
break;
case TypeCode.SByte:
enumValueLong = (byte)((sbyte)enumValueObject);
break;
case TypeCode.Int16:
enumValueLong = (ushort)((short)enumValueObject);
break;
case TypeCode.Int32:
enumValueLong = (uint)((int)enumValueObject);
break;
case TypeCode.Int64:
enumValueLong = (ulong)((long)enumValueObject);
break;
case TypeCode.UInt16:
enumValueLong = (ushort)enumValueObject;
break;
case TypeCode.UInt32:
enumValueLong = (uint)enumValueObject;
break;
case TypeCode.UInt64:
enumValueLong = (ulong)enumValueObject;
break;
default:
return false; // should never happen
}
retVal |= enumValueLong;
}
result = (TEnum)Enum.ToObject(enumType, retVal);
return true;
}
// the value may be a number, so parse it directly
switch (enumTypeCode) {
case TypeCode.SByte:
sbyte sb;
if (!SByte.TryParse(value, out sb))
return false;
result = (TEnum)Enum.ToObject(enumType, sb);
break;
case TypeCode.Byte:
byte b;
if (!Byte.TryParse(value, out b))
return false;
result = (TEnum)Enum.ToObject(enumType, b);
break;
case TypeCode.Int16:
short i16;
if (!Int16.TryParse(value, out i16))
return false;
result = (TEnum)Enum.ToObject(enumType, i16);
break;
case TypeCode.UInt16:
ushort u16;
if (!UInt16.TryParse(value, out u16))
return false;
result = (TEnum)Enum.ToObject(enumType, u16);
break;
case TypeCode.Int32:
int i32;
if (!Int32.TryParse(value, out i32))
return false;
result = (TEnum)Enum.ToObject(enumType, i32);
break;
case TypeCode.UInt32:
uint u32;
if (!UInt32.TryParse(value, out u32))
return false;
result = (TEnum)Enum.ToObject(enumType, u32);
break;
case TypeCode.Int64:
long i64;
if (!Int64.TryParse(value, out i64))
return false;
result = (TEnum)Enum.ToObject(enumType, i64);
break;
case TypeCode.UInt64:
ulong u64;
if (!UInt64.TryParse(value, out u64))
return false;
result = (TEnum)Enum.ToObject(enumType, u64);
break;
default:
return false; // should never happen
}
return true;
}
这篇关于Enum.TryParse在.NET 3.5的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文