C# TypeConverter无法从某些基类型转换为相同的基类型
为什么返回C# TypeConverter无法从某些基类型转换为相同的基类型,c#,type-conversion,C#,Type Conversion,为什么返回true: TypeDescriptor.GetConverter(typeof(double)).CanConvertTo(typeof(double)); TypeDescriptor.GetConverter(typeof(int)).CanConvertTo(typeof(int)); 当这些返回值false TypeDescriptor.GetConverter(typeof(decimal)).CanConvertTo(typeof(decimal));
true
:
TypeDescriptor.GetConverter(typeof(double)).CanConvertTo(typeof(double));
TypeDescriptor.GetConverter(typeof(int)).CanConvertTo(typeof(int));
当这些返回值false
TypeDescriptor.GetConverter(typeof(decimal)).CanConvertTo(typeof(decimal));
TypeDescriptor.GetConverter(typeof(bool)).CanConvertTo(typeof(bool));
事件,考虑到GetConverter返回的所有转换器应仅将类型转换为字符串或从字符串转换为:
我正在使用.NET Framework 4.5.2。
十进制转换器
(以及双转换器
和Int32Converter
)重写CanConvertTo
,以指示它可以转换为字符串(因为base.CanConvertTo
就是这样做的)和所有CLR基元类型。发件人:
从CLR的角度来看,decimal
不是基本类型,因此当传递typeof(decimal)
时,转换器返回false
booleanConvertto
不会覆盖CanConvertTo
,因此它属于只允许转换为字符串的基本实现:
public virtual bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return (destinationType == typeof(string));
}
如果你问为什么它是这样设计的,那么只有框架设计师可以说,但我怀疑这是因为这只是一个简单的检查,看看你是否试图从一个类型转换为相同的类型
考虑到它们的目的是将非字符串类型转换为字符串或从字符串转换为字符串,以便在属性网格、XAML等中显示,因此它不完全支持非字符串转换也就不足为奇了。Boolean
,Char
,DateTime
,String
和Object
的TypeConverter
继承自BaseTypeConverter
,不覆盖CanConvertTo
,仅当传递的类型为String
时才会返回true。这就是为什么TypeDescriptor.GetConverter(typeof(bool)).CanConvertTo(typeof(bool))
为false
用于字节
,双字节
,Int16
,Int32
,Int64
,SByte
,单字节
,UInt16
,UInt32
,的类型转换器,和UInt64
都是从BaseNumberConverter
派生的,对于字符串或基元类型的类型,cancoverto
返回true
Decimal
也继承自BaseNumberConverter
,但由于它不是原语,将Decimal类型传递给CanConvertTo
将导致false。这就是为什么TypeDescriptor.GetConverter(typeof(decimal)).CanConvertTo(typeof(decimal))
为false
以下是CanConvertTo
结果的完整图表:
FROM/TO Bol Byt Chr DTm Dec Dbl I16 I32 I64 SBt Sng Str Obj U16 U32 U64
Boolean +
Byte + + + + + + + + + + + + +
Char +
DateTime +
Decimal + + + + + + + + + + + + +
Double + + + + + + + + + + + + +
Int16 + + + + + + + + + + + + +
Int32 + + + + + + + + + + + + +
Int64 + + + + + + + + + + + + +
SByte + + + + + + + + + + + + +
Single + + + + + + + + + + + + +
String +
Object +
UInt16 + + + + + + + + + + + + +
UInt32 + + + + + + + + + + + + +
UInt64 + + + + + + + + + + + + +
类型及其转换器:
Type Converter class Converter inherits from
---------- ------------------ -----------------------
Boolean BooleanConverter TypeConverter
Byte ByteConverter BaseNumberConverter
Char CharConverter TypeConverter
DateTime DateTimeConverter TypeConverter
Decimal DecimalConverter BaseNumberConverter
Double DoubleConverter BaseNumberConverter
Int16 Int16Converter BaseNumberConverter
Int32 Int32Converter BaseNumberConverter
Int64 Int64Converter BaseNumberConverter
SByte SByteConverter BaseNumberConverter
Single SingleConverter BaseNumberConverter
String StringConverter TypeConverter
Object TypeConverter Object
UInt16 UInt16Converter BaseNumberConverter
UInt32 UInt32Converter BaseNumberConverter
UInt64 UInt64Converter BaseNumberConverter
UInt32 UInt32Converter BaseNumberConverter
UInt64 UInt64Converter BaseNumberConverter
我不确定是否有人,除了BCL团队的一名成员,能够真正解释这是否是一个真正的原因,或者这只是一个疏忽。我确实看到了检查基本类型的逻辑,而十进制不是,从而解释了与十进制的差异。但是为什么不支持十进制呢?布尔不是一种原始类型吗?我只是用反射,typeof(bool)检查了一下。IsPrimative是真的,所以我不知道“从CLR的角度来看bool不是primative类型”是什么意思。@DanielGimenez我错了。有趣的是,这意味着decimalconvertto.CanConvertTo(typeof(bool))
返回true,这毫无意义。它似乎转换为0代码< >代码>错误>代码>以及其他任何到<代码>真的< /C> > C++。我认为在马蒂厄之前,没有人会想到这个。为什么不能将布尔值转换为数字,而将数字转换为布尔值似乎是一个疏忽。@DanielGimenez我怀疑将数字转换为布尔值是原始设计的一部分-其目的是能够将值转换为字符串(用于在属性框中显示和嵌入标记)以及从字符串进行解析(当在属性网格或标记中更改设置时)。此外,由于它是不可逆的(如何将true转换为4?),因此不允许它是有意义的。
Type Converter class Converter inherits from
---------- ------------------ -----------------------
Boolean BooleanConverter TypeConverter
Byte ByteConverter BaseNumberConverter
Char CharConverter TypeConverter
DateTime DateTimeConverter TypeConverter
Decimal DecimalConverter BaseNumberConverter
Double DoubleConverter BaseNumberConverter
Int16 Int16Converter BaseNumberConverter
Int32 Int32Converter BaseNumberConverter
Int64 Int64Converter BaseNumberConverter
SByte SByteConverter BaseNumberConverter
Single SingleConverter BaseNumberConverter
String StringConverter TypeConverter
Object TypeConverter Object
UInt16 UInt16Converter BaseNumberConverter
UInt32 UInt32Converter BaseNumberConverter
UInt64 UInt64Converter BaseNumberConverter
UInt32 UInt32Converter BaseNumberConverter
UInt64 UInt64Converter BaseNumberConverter