我正在尝试构建更快版本的Convert.ChangeType
。该类型在运行时提供。该函数用于解析文本文件等字符串。
public static object ConvertTo(Type t, string s)
{
if (string.IsNullOrWhiteSpace(s) || s == null || Convert.IsDBNull(s)) return null;
if (t == typeof(string)) return s;
if (t == typeof(DateTime)) { .... /* parse and return it */ }
if (t == typeof(int)) { return int.Parse(s); }
....
return Convert.ChangeType(s, t, CultureInfo.InvariantCulture); // Slowest
}
但是,它在分析中仍然是最慢的部分。这是一种提高速度的方法吗?
答案 0 :(得分:1)
将字符串转换为另一种类型本身就很昂贵。但是,Convert.ChangeType
正在进行虚拟接口调用和装箱/拆箱,你可以避免。
这是它在幕后做的事情:
public static object ChangeType(object value, Type conversionType, IFormatProvider provider)
{
if (conversionType == (Type) null)
throw new ArgumentNullException("conversionType");
if (value == null)
{
if (conversionType.IsValueType)
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCastNullToValueType"));
else
return (object) null;
}
else
{
IConvertible convertible = value as IConvertible;
if (convertible == null)
{
if (value.GetType() == conversionType)
return value;
else
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_IConvertible"));
}
else
{
RuntimeType runtimeType = conversionType as RuntimeType;
if (runtimeType == Convert.ConvertTypes[3])
return (object) (bool) (convertible.ToBoolean(provider) ? 1 : 0);
if (runtimeType == Convert.ConvertTypes[4])
return (object) convertible.ToChar(provider);
if (runtimeType == Convert.ConvertTypes[5])
return (object) convertible.ToSByte(provider);
if (runtimeType == Convert.ConvertTypes[6])
return (object) convertible.ToByte(provider);
if (runtimeType == Convert.ConvertTypes[7])
return (object) convertible.ToInt16(provider);
if (runtimeType == Convert.ConvertTypes[8])
return (object) convertible.ToUInt16(provider);
if (runtimeType == Convert.ConvertTypes[9])
return (object) convertible.ToInt32(provider);
if (runtimeType == Convert.ConvertTypes[10])
return (object) convertible.ToUInt32(provider);
if (runtimeType == Convert.ConvertTypes[11])
return (object) convertible.ToInt64(provider);
if (runtimeType == Convert.ConvertTypes[12])
return (object) convertible.ToUInt64(provider);
if (runtimeType == Convert.ConvertTypes[13])
return (object) convertible.ToSingle(provider);
if (runtimeType == Convert.ConvertTypes[14])
return (object) convertible.ToDouble(provider);
if (runtimeType == Convert.ConvertTypes[15])
return (object) convertible.ToDecimal(provider);
if (runtimeType == Convert.ConvertTypes[16])
return (object) convertible.ToDateTime(provider);
if (runtimeType == Convert.ConvertTypes[18])
return (object) convertible.ToString(provider);
if (runtimeType == Convert.ConvertTypes[1])
return value;
else
return convertible.ToType(conversionType, provider);
}
}
}
这是它使用的类型数组:
internal static readonly RuntimeType[] ConvertTypes = new RuntimeType[19]
{
(RuntimeType) typeof (Empty),
(RuntimeType) typeof (object),
(RuntimeType) typeof (DBNull),
(RuntimeType) typeof (bool),
(RuntimeType) typeof (char),
(RuntimeType) typeof (sbyte),
(RuntimeType) typeof (byte),
(RuntimeType) typeof (short),
(RuntimeType) typeof (ushort),
(RuntimeType) typeof (int),
(RuntimeType) typeof (uint),
(RuntimeType) typeof (long),
(RuntimeType) typeof (ulong),
(RuntimeType) typeof (float),
(RuntimeType) typeof (double),
(RuntimeType) typeof (Decimal),
(RuntimeType) typeof (DateTime),
(RuntimeType) typeof (object),
(RuntimeType) typeof (string)
};