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