我需要检查一下对象是否可以转换为特定的DataType,并想出了这个:
public static bool TryParseAll(System.Type typeToConvert, object valueToConvert)
{
bool succeed = false;
switch (typeToConvert.Name.ToUpper())
{
case "DOUBLE":
double d;
succeed = double.TryParse(valueToConvert.ToString(), out d);
break;
case "DATETIME":
DateTime dt;
succeed = DateTime.TryParse(valueToConvert.ToString(), out dt);
break;
case "INT16":
Int16 i16;
succeed = Int16.TryParse(valueToConvert.ToString(), out i16);
break;
case "INT":
Int32 i32;
succeed = Int32.TryParse(valueToConvert.ToString(), out i32);
break;
case "INT32":
Int32 i322;
succeed = Int32.TryParse(valueToConvert.ToString(), out i322);
break;
case "INT64":
Int64 i64;
succeed = Int64.TryParse(valueToConvert.ToString(), out i64);
break;
case "BOOLEAN":
bool b;
succeed = Boolean.TryParse(valueToConvert.ToString(), out b);
break;
case "BOOL":
bool b1;
succeed = bool.TryParse(valueToConvert.ToString(), out b1);
break;
}
return succeed;
}
我想知道除此之外有什么方法吗?哪个更有活力,效率更高?
谢谢!
答案 0 :(得分:3)
您应该使用TypeDescriptor类:
public static T Convert<T>(this string input)
{
var converter = TypeDescriptor.GetConverter(typeof(T));
if(converter != null)
{
//Cast ConvertFromString(string text) : object to (T)
return (T)converter.ConvertFromString(input);
}
return default(T);
}
当然,如果转换失败,这将抛出异常,因此您需要尝试/捕获它。
答案 1 :(得分:3)
这是我的通用TryParse
方法版本。
我相信你也可以使用这个版本:
double pi;
if(ValueTypeHelper.TryParse("3.14159", out pi)) {
// .. pi = 3.14159
}
...
string eStr = "2.71828";
float e;
if(eStr.TryParse(out e)) {
// .. e = 2.71828f
}
...
static class ValueTypeHelper {
static IDictionary<Type, Delegate> cache = new Dictionary<Type, Delegate>();
public static bool TryParse<T>(this string valueStr, out T result) {
Delegate d = null;
if(!cache.TryGetValue(typeof(T), out d)) {
var mInfos = typeof(T).GetMember("TryParse", MemberTypes.Method, BindingFlags.Static | BindingFlags.Public);
if(mInfos.Length > 0) {
var s = Expression.Parameter(typeof(string));
var r = Expression.Parameter(typeof(T).MakeByRefType());
d = Expression.Lambda<TryParseDelegate<T>>(
Expression.Call(mInfos[0] as MethodInfo, s, r), s, r).Compile();
}
cache.Add(typeof(T), d);
}
result = default(T);
TryParseDelegate<T> tryParse = d as TryParseDelegate<T>;
return (tryParse != null) && tryParse(valueStr, out result);
}
delegate bool TryParseDelegate<T>(string valueStr, out T result);
}
答案 2 :(得分:1)
我结合了DmitryG&RezaRahmati的建议解决方案:
static class GenericValueConverter
{
public static bool TryParse<T>(this string input, out T result)
{
bool isConversionSuccessful = false;
result = default(T);
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
try
{
result = (T)converter.ConvertFromString(input);
isConversionSuccessful = true;
}
catch { }
}
return isConversionSuccessful;
}
}
void Main()
{
double pi;
if (GenericValueConverter.TryParse("3,14159", out pi)) //Use right decimal point seperator for local culture
{
pi.Dump(); //ConsoleWriteline for LinqPad
//pi=3,14159
}
string dtStr = "2016-12-21T16:34:22";
DateTime dt;
if (dtStr.TryParse(out dt))
{
dt.Dump(); //ConsoleWriteline for LinqPad
//dt=21.12.2016 16:34:22
}
string guidStr = "D430831B-03B0-44D5-A971-4E73AF96B5DF";
Guid guid;
if (guidStr.TryParse(out guid))
{
guid.Dump(); //ConsoleWriteline for LinqPad
//guid=d430831b-03b0-44d5-a971-4e73af96b5df
}
}