Sto lavorando a un'implementazione IValueConverter
che converte i valori bool?
. Per motivi di versatilità, ho deciso di utilizzare TypeConverter
per convertire il valore di input in bool?
. Dal momento che il suo scopo principale è quello di essere utilizzato come convertitore per i binding XAML, vorrei evitare di generare eccezioni in quanto si traduce in una significativa diminuzione delle prestazioni dell'interfaccia utente. Per fare questo ho provato ad utilizzare TypeConverter.IsValid
metodo, ma sono imbattuto in un comportamento singolare, di cui un esempio è mostrato nel seguente codice:Incoerenza nel comportamento del TypeConverter?
//returned converter is a NullableConverter
var converter = TypeDescriptor.GetConverter(typeof(bool?));
//this method returns false
converter.IsValid(string.Empty);
//yet this method returns null without throwing an exception
converter.ConvertFrom(string.Empty);
Forse mi sbaglio, ma mi aspetto il metodo IsValid
per tornare false
ogni volta che un valore non può essere convertito e true
in caso contrario, ma chiaramente questo non è il caso con una stringa vuota e NullableConverter
(lo stesso comportamento può essere osservato per altri tipi nullable).
È un errore o piuttosto una scelta di progettazione? E se quest'ultimo, ci sono altri casi simili?
EDIT
Dopo aver ispezionato la source code per NullableConverter
Credo di aver trovato la ragione di questo comportamento. Ecco il IsValid
realizzazione:
public override bool IsValid(ITypeDescriptorContext context, object value) {
if (simpleTypeConverter != null) {
object unwrappedValue = value;
if (unwrappedValue == null) {
return true; // null is valid for nullable.
}
else {
return simpleTypeConverter.IsValid(context, unwrappedValue);
}
}
return base.IsValid(context, value);
}
Nel mio caso il simpleTypeConverter
è di tipo BooleanConverter
e, comprensibilmente, restituisce false
per string.Empty
. D'altra parte, ecco la ConvertFrom
attuazione:
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
if (value == null || value.GetType() == this.simpleType) {
return value;
}
else if (value is String && String.IsNullOrEmpty(value as String)) {
return null;
}
else if (this.simpleTypeConverter != null) {
object convertedValue = this.simpleTypeConverter.ConvertFrom(context, culture, value);
return convertedValue;
}
else {
return base.ConvertFrom(context, culture, value);
}
}
Ovviamente, string.Empty
cade nella seconda if
economico, quindi il risultato senza null
un'eccezione.
Conoscendo il motivo di questo comportamento, la domanda rimane ancora - è una svista, o è destinato a funzionare in questo modo? Ho inviato uno bug report e pubblicheremo qualsiasi conclusione per uscirne.
Quando provo il tuo esempio 'IsValid' genera un' FormatException' con messaggio 'String non è stato riconosciuto come booleano valido. Tuttavia, la documentazione dice che" Avvio in .NET Framework 4, il metodo IsValid rileva eccezioni dal Metodi CanConvertFrom e ConvertFrom Se il tipo di valore di input causa CanConvertFrom per restituire false, o se il valore di input fa sì che ConvertFrom generi un'eccezione, il metodo IsValid restituisce false. " –
Anche divertente che 'myNullableConverter.ConvertToString (null)' restituisca una stringa vuota. Immagino che 'null' non sia valido per un' Nullable '? –
@MariusBancila Ho appena testato le versioni del framework di targeting del codice che vanno dalla 2.0 alla 4.5.1, e in ogni caso né "ConvertFrom" né "IsValid" hanno generato un'eccezione. È interessante notare che, fino alla versione 3.5 inclusa "IsValid' restituito' true' ... È possibile che "ConvertFrom" "inghiotte" l'eccezione? – Grx70