如果您有一组已知的类型要转换,您可以执行一系列if/elseif/elseif/else
(或switch/case
在类型名称上)基本上将其分配给专门的解析方法。这应该很快。这如@Fabio's answer中所述。
如果您仍然有性能问题,您还可以创建一个查找表,让您根据需要添加新的解析方法来支持它们:
给定一些基本的解析包装器:
public delegate bool TryParseMethod<T>(string input, out T value);
public interface ITryParser
{
bool TryParse(string input, out object value);
}
public class TryParser<T> : ITryParser
{
private TryParseMethod<T> ParsingMethod;
public TryParser(TryParseMethod<T> parsingMethod)
{
this.ParsingMethod = parsingMethod;
}
public bool TryParse(string input, out object value)
{
T parsedOutput;
bool success = ParsingMethod(input, out parsedOutput);
value = parsedOutput;
return success;
}
}
然后,您可以设置一个转换助手来进行查找并调用适当的解析器:
public static class DataConversion
{
private static Dictionary<Type, ITryParser> Parsers;
static DataConversion()
{
Parsers = new Dictionary<Type, ITryParser>();
AddParser<DateTime>(DateTime.TryParse);
AddParser<int>(Int32.TryParse);
AddParser<double>(Double.TryParse);
AddParser<decimal>(Decimal.TryParse);
AddParser<string>((string input, out string value) => {value = input; return true;});
}
public static void AddParser<T>(TryParseMethod<T> parseMethod)
{
Parsers.Add(typeof(T), new TryParser<T>(parseMethod));
}
public static bool Convert<T>(string input, out T value)
{
object parseResult;
bool success = Convert(typeof(T), input, out parseResult);
if (success)
value = (T)parseResult;
else
value = default(T);
return success;
}
public static bool Convert(Type type, string input, out object value)
{
ITryParser parser;
if (Parsers.TryGetValue(type, out parser))
return parser.TryParse(input, out value);
else
throw new NotSupportedException(String.Format("The specified type \"{0}\" is not supported.", type.FullName));
}
}
那么用法可能是这样的:
//for a known type at compile time
int value;
if (!DataConversion.Convert<int>("3", out value))
{
//log failure
}
//or for unknown type at compile time:
object value;
if (!DataConversion.Convert(myType, dataValue, out value))
{
//log failure
}
这可能会扩展泛型以避免object
装箱和类型转换,但就目前而言,这很好用;如果您从中获得可衡量的性能,也许只有优化该方面。
编辑:您可以更新该DataConversion.Convert
方法,以便如果它没有注册指定的转换器,它可以回退到您的TypeConverter
方法或引发适当的异常。如果您想拥有一个包罗万象的内容,或者只是拥有预定义的支持类型集并避免try/catch
重蹈覆辙,这取决于您。就目前而言,代码已更新为抛出一个NotSupportedException
指示不受支持的类型的消息。随意调整,因为它是有道理的。性能方面,也许做一个包罗万象是有意义的,因为一旦你为最常用的类型指定了专门的解析器,这些可能会越来越少。