Я работаю над реализацией IValueConverter
, которая преобразует значения bool?
. Ради универсальности я решил использовать TypeConverter
для преобразования входного значения в bool?
. Поскольку его основная цель заключается в использовании конвертера для привязок XAML, я бы хотел избежать исключения, поскольку это привело к значительному снижению производительности пользовательского интерфейса. Для этого я попытался использовать метод TypeConverter.IsValid
, но натолкнулся на своеобразное поведение, пример которого показан в следующем коде:
//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);
Возможно, я ошибаюсь, но я бы ожидал, что метод IsValid
вернет false
всякий раз, когда значение не может быть преобразовано и true
в противном случае, но ясно, что не случай с пустой строкой и NullableConverter
(такое же поведение наблюдается и для других типов с нулевым значением).
Это ошибка или, скорее, выбор дизайна? И если последнее, есть ли другие подобные случаи?
ИЗМЕНИТЬ
После проверки исходного кода для NullableConverter
, я думаю, что нашел причину такого поведения. Здесь реализация IsValid
:
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);
}
В моем случае simpleTypeConverter
имеет тип BooleanConverter
и, по понятным причинам, он возвращает false
для string.Empty
. С другой стороны, здесь реализация ConvertFrom
:
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);
}
}
Очевидно, что string.Empty
попадает во второй оператор if
, поэтому результат null
не содержит исключения.
Зная причину такого поведения, вопрос все еще остается - это надзор, или он намерен работать таким образом? Я отправил отчет об ошибке и опубликую любые выводы, чтобы выйти из него.