Ich glaube, ich sollte erklären, warum die Funktion nicht funktioniert:
1- Die Zeile, die die Ausnahme auslöst, lautet wie folgt:
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", new object[]
{
value.GetType().FullName,
targetType.FullName
}));
in der Tat die Funktion Suche im Array Convert.ConvertTypes sieht danach, ob der targer ein Enum ist und wenn nichts gefunden wird, wirft er die obige Ausnahme.
2- die Convert.ConvertTypes initialisiert als:
Convert.ConvertTypes = new RuntimeType[]
{
(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)
};
So seit dem int?
ist nicht in der ConvertTypes Array und kein Enum die Ausnahme ausgelöst wird.
So fortzusetzen, für die Funktion Convert.ChnageType Sie müssen arbeiten:
Das Objekt umgewandelt werden IConvertible ist
Der Zieltyp innerhalb der ConvertTypes und nicht Empty
noch DBNull
(Es gibt einen explict Test auf den beiden mit throw Ausnahme)
Dieses Verhalten ist, weil int
(und alle anderen Standardtypen) verwendet Convert.DefaultToType
als IConvertibale.ToType implementation. and here is the code of the
DefaultToType extracted
ILSpy
internal static object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
{
if (targetType == null)
{
throw new ArgumentNullException("targetType");
}
RuntimeType left = targetType as RuntimeType;
if (left != null)
{
if (value.GetType() == targetType)
{
return value;
}
if (left == Convert.ConvertTypes[3])
{
return value.ToBoolean(provider);
}
if (left == Convert.ConvertTypes[4])
{
return value.ToChar(provider);
}
if (left == Convert.ConvertTypes[5])
{
return value.ToSByte(provider);
}
if (left == Convert.ConvertTypes[6])
{
return value.ToByte(provider);
}
if (left == Convert.ConvertTypes[7])
{
return value.ToInt16(provider);
}
if (left == Convert.ConvertTypes[8])
{
return value.ToUInt16(provider);
}
if (left == Convert.ConvertTypes[9])
{
return value.ToInt32(provider);
}
if (left == Convert.ConvertTypes[10])
{
return value.ToUInt32(provider);
}
if (left == Convert.ConvertTypes[11])
{
return value.ToInt64(provider);
}
if (left == Convert.ConvertTypes[12])
{
return value.ToUInt64(provider);
}
if (left == Convert.ConvertTypes[13])
{
return value.ToSingle(provider);
}
if (left == Convert.ConvertTypes[14])
{
return value.ToDouble(provider);
}
if (left == Convert.ConvertTypes[15])
{
return value.ToDecimal(provider);
}
if (left == Convert.ConvertTypes[16])
{
return value.ToDateTime(provider);
}
if (left == Convert.ConvertTypes[18])
{
return value.ToString(provider);
}
if (left == Convert.ConvertTypes[1])
{
return value;
}
if (left == Convert.EnumType)
{
return (Enum)value;
}
if (left == Convert.ConvertTypes[2])
{
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
}
if (left == Convert.ConvertTypes[0])
{
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_Empty"));
}
}
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", new object[]
{
value.GetType().FullName,
targetType.FullName
}));
}
in der anderen Hand die Besetzung von Nullable-Klasse implementiert wird selbst und die Definition lautet:
public static implicit operator T?(T value)
{
return new T?(value);
}
public static explicit operator T(T? value)
{
return value.Value;
}
Ich denke, vielleicht coz 'Nullable' implementiert nicht 'IConvertible' –
V4Vendetta
Dies ist ziemlich grundlegend. Nullable ist speziell, wenn Sie es in ein Objekt einfügen, wird es entweder null oder wird zu einem Boxed-Wert des Werttyps. Also nach einem Int fragen? in einem Objekt gespeichert ist einfach nicht sinnvoll. Fragen Sie einfach nach int. –