【发布时间】:2015-08-05 16:55:04
【问题描述】:
我正在开发一个IValueConverter 实现,它将转换bool? 值。为了通用性,我决定使用TypeConverter 将输入值转换为bool?。由于它的主要目的是用作 XAML 绑定的转换器,我想避免抛出异常,因为它会导致 UI 性能显着下降。为此,我尝试使用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 的情况(对于其他可为空的类型也可以观察到相同的行为)。
这是一个错误还是一个设计选择?如果是后者,是否还有其他类似的案例?
编辑
在检查了source code 的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 类型,可以理解的是,它为 string.Empty 返回 false。另一方面,这是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 结果无一例外。
知道这种行为的原因后,问题仍然存在 - 是疏忽,还是打算以这种方式工作?我已经提交了bug report,并将发布任何结论。
【问题讨论】:
-
当我尝试您的示例时,
IsValid会抛出带有消息String was not recognized as a valid Boolean.的FormatException但是,文档说“从 .NET Framework 4 开始,IsValid 方法从 CanConvertFrom 和 ConvertFrom 捕获异常方法。如果输入值类型导致 CanConvertFrom 返回 false,或者如果输入值导致 ConvertFrom 引发异常,则 IsValid 方法返回 false。" -
myNullableConverter.ConvertToString(null)返回一个空字符串也很有趣。我猜null对Nullable<T>无效? -
@MariusBancila 我刚刚测试了从 2.0 到 4.5.1 的代码定位框架版本,在任何情况下,
ConvertFrom和IsValid都没有抛出异常。有趣的是,直到并包括版本 3.5IsValid返回true...ConvertFrom是否有可能“吞下”异常? -
根据文档,它应该从 .NET 4.0 开始吞下异常。但我在 .NET 4.5 项目中进行了测试。所以我不明白。
-
这不是错误。来自 TypeConverter.IsValid 的 MSDN 描述:“IsValid 方法用于验证类型内的值而不是确定值是否可以转换为给定类型。例如,可以使用 IsValid确定给定值是否对枚举类型有效。"
标签: c# typeconverter