將字符串轉換爲另一種類型本身就很昂貴。但是,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)
};
嘗試使用一些鍵集合來存儲轉換的功能,如'詞典<類型,類似'HashTable'的Func
這就是爲什麼你應該首先避免這種情況。開始時,這是一個固有的昂貴的問題,將某些東西轉換爲編譯時未知的類型。你應該很少會遇到這種情況。在大多數情況下,你應該在編譯時知道你想要的類型。另外請記住,如果只有一些銀彈來解決這個問題,你不認爲這將被用作'Convert.ChangeType'的定義嗎? – Servy 2014-09-04 19:42:36
@EugenePodskal只有少數幾種類型不可能產生有意義的區別。他必須有幾十種甚至數百種類型才能開始重要。 – Servy 2014-09-04 19:43:10