Tôi nghĩ rằng tôi nên giải thích lý do tại sao chức năng không hoạt động:
1- Dòng ném ngoại lệ như sau:
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", new object[]
{
value.GetType().FullName,
targetType.FullName
}));
trên thực tế, chức năng tìm kiếm trong mảng Chuyển đổi.ConvertTypes sau đó nó thấy nếu targer là một Enum và khi không có gì được tìm thấy nó ném ngoại lệ ở trên.
2- các Convert.ConvertTypes được khởi tạo như:
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)
};
Vì vậy, kể từ khi int?
không nằm trong mảng ConvertTypes và không phải là một Enum ngoại lệ được ném.
Vì vậy, để tiếp tục, cho hàm Convert.ChnageType để làm việc bạn có:
Đối tượng được chuyển đổi là IConvertible
loại
Mục tiêu nằm trong ConvertTypes và không Empty
cũng không DBNull
(Có một thử nghiệm khám phá về hai trường hợp có ngoại lệ ném)
Hành vi này là do int
(và tất cả các loại mặc định khác) sử dụng Convert.DefaultToType
như IConvertibale.ToType implementation. and here is the code of the
DefaultToType extracted
sử dụng 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
}));
}
trong Mặt khác các diễn viên được thực hiện bởi lớp Nullable bản thân và định nghĩa là:
public static implicit operator T?(T value)
{
return new T?(value);
}
public static explicit operator T(T? value)
{
return value.Value;
}
Tôi đoán có thể coz 'Nullable' không thực hiện 'IConvertible' –
V4Vendetta
Điều này là khá cơ bản. Nullable là đặc biệt, khi bạn đặt nó vào một đối tượng thì nó trở thành null hoặc trở thành một giá trị đóng hộp của kiểu giá trị. Vì vậy, yêu cầu cho một int? được lưu trữ trong một đối tượng không có ý nghĩa. Chỉ cần yêu cầu int. –