기능이 작동하지 않는 이유를 설명해야한다고 생각합니다.
1- 예외를 발생시키는 줄은 다음과 같습니다.
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", new object[]
{
value.GetType().FullName,
targetType.FullName
}));
실제로 배열 Convert.ConvertTypes에서 함수 검색은 targer가 Enum인지 확인하고 아무것도 발견되지 않으면 위의 예외를 throw합니다.
2- Convert.ConvertTypes는 다음과 같이 초기화됩니다.
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)
};
따라서 int?가 ConvertTypes 배열에없고 Enum이 아니므로 예외가 발생합니다.
다시 시작하려면 Convert.ChnageType 함수가 작동하려면 다음을 수행하십시오.
변환 할 개체는 IConvertible입니다.
대상 유형이 ConvertTypes 내에 있으며 Empty또는 아닙니다 DBNull(두 가지 예외가 발생하는 경우 명시 적 테스트가 있습니다).
이 동작은 int(및 기타 모든 기본 유형)이 다음을 사용 Convert.DefaultToType하여 IConvertibale.ToType implementation. and here is the code of theDefaultToType으로 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
}));
}
반면에 캐스트는 Nullable 클래스 자체에 의해 구현되며 정의는 다음과 같습니다.
public static implicit operator T?(T value)
{
return new T?(value);
}
public static explicit operator T(T? value)
{
return value.Value;
}
Nullable<T>구현하지 않습니다IConvertible