TypeConverter cannot convert from some base types to same base types
Boolean
, Char
, DateTime
, String
and Object
's TypeConverter
inherit from BaseTypeConverter
and don't overwrite CanConvertTo
, which return true only if the type passed is of type string
. That is why TypeDescriptor.GetConverter(typeof(bool)).CanConvertTo(typeof(bool))
is false.
The type converters for Byte
, Double
, Int16
, Int32
, Int64
, SByte
, Single
, UInt16
, UInt32
, and UInt64
are all derived from BaseNumberConverter
which returns true for CanCovertTo
for types that are strings or primitive types.
Decimal
does inherit from BaseNumberConverter
as well, but since it's not a primitive, passing decimal type to CanConvertTo
will result in false. That is why TypeDescriptor.GetConverter(typeof(decimal)).CanConvertTo(typeof(decimal))
is false.
Here's a full chart for the results of 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 + + + + + + + + + + + + +
Types and their converters:
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
DecimalConverter
(as well as DoubleConverter
and Int32Converter
) overrides CanConvertTo
to indicate it can convert to strings (because that's what base.CanConvertTo
does) and all CLR primitive types. From the Reference Source:
public override bool CanConvertTo(ITypeDescriptorContext context, Type t)
{
if (base.CanConvertTo(context, t) || t.IsPrimitive) {
return true;
}
return false;
}
decimal
is NOT a primitive type from the CLR's perspective, so the converter returns false
when passed typeof(decimal)
.
BooleanConverter
does not override CanConvertTo
, so it falls to the base implementation which only allows a conversion to string
:
public virtual bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return (destinationType == typeof(string));
}
If you're asking why it's designed that way, then only the Framework designers can say, but I suspect it's because it's a trivial check to see if you're trying to convert from one type to the same type.
Considering that their purpose is to convert non-string types to/from strings for displaying in property grids, XAML, etc., it's not surprising that it doesn't fully support non-string conversions.