2015-06-16 2 views
11

Почему те возвращают true:TypeConverter не может конвертировать из некоторых базовых типов в тех же базовых типов

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.

+1

Я не уверен, если кто-нибудь, кроме члена BCL команды, действительно может объяснить если бы была настоящая причина этого, или это был просто надзор. Я вижу логику в [BaseNumberConverter.CanConvertTo] (http://referencesource.microsoft.com/System/R/0ca895b4d1e6191c.html), которая проверяет примитивные типы, которые Десятичные * не *, объясняя тем самым расхождение с Decimal. Но почему бы не поддержать десятичное? –

ответ

7

DecimalConverter (а также DoubleConverter и Int32Converter) переопределяет CanConvertTo, чтобы указать его можно преобразовать в строки (потому что это то, что делает base.CanConvertTo) и все примитивные типы CLR. От the Reference Source:

public override bool CanConvertTo(ITypeDescriptorContext context, Type t) 
{ 
    if (base.CanConvertTo(context, t) || t.IsPrimitive) { 
     return true; 
    } 
    return false; 
} 

decimal НЕ примитивный тип с точки зрения CLR, поэтому преобразователь возвращается false при передаче typeof(decimal).

BooleanConverter не отменяет CanConvertTo, поэтому он падает на базовую реализацию, которая позволяет только преобразование в string:

public virtual bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 
{ 
    return (destinationType == typeof(string)); 
} 

Если вы спрашиваете почему он разработан таким образом, то только рамочные дизайнеров могу сказать, но я подозреваю, что это потому, что это тривиальная проверка, чтобы увидеть, пытаетесь ли вы конвертировать из одного типа в тот же тип.

Учитывая, что их целью является преобразование нестроковых типов в/из строк для отображения в сетках свойств, XAML и т. Д., Неудивительно, что он не поддерживает полностью нестрочные преобразования.

+1

Не является ли bool примитивным типом? https://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx – Matthieu

+0

Я только что проверил с помощью Reflection, typeof (bool) .IsPrimative - это правда, поэтому я не знаю, что "bool NOT примитивные типы с точки зрения CLR ». –

+0

@Matthieu Вы правы - ответьте на обновления. –

1

Boolean, Char, DateTime, String и Object TypeConverter наследуют от BaseTypeConverter и не перезаписывают CanConvertTo, которые возвращают true, только если переданный тип имеет строку типа. Вот почему TypeDescriptor.GetConverter(typeof(bool)).CanConvertTo(typeof(bool)) ложно.

Преобразователи типа для байтов, двоичных, Int16, Int32, Int64, SByte, Single, UInt16, UInt32 и UInt64 являются производными от BaseNumberConverter, который возвращает true для CanCovertTo для типов, которые являются строками или примитивными типами.

Десятичный код также наследуется от BaseNumberConverter, но поскольку он не является примитивным, он передает тип decimail в CanConvertTo, что приведет к ложному. Вот почему TypeDescriptor.GetConverter(typeof(decimal)).CanConvertTo(typeof(decimal)) неверно.

Вот полный график для результатов 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 
Смежные вопросы