我正在开发一个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);
Run Code Online (Sandbox Code Playgroud)
也许我错了,但是我希望只要一个值无法转换就会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);
}
Run Code Online (Sandbox Code Playgroud)
在我的情况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);
}
}
Run Code Online (Sandbox Code Playgroud)
显然,string.Empty落入第二个if陈述,因此null结果没有例外.
知道这种行为的原因仍然存在问题 - 这是一种疏忽,还是打算以这种方式工作?我已经提交了一份错误报告,并将发布任何结论.
不同的人在某些情况下的期望可能不同,但对我来说,在这种情况下框架给出的行为似乎是合理的。
例如:在以下情况下,这种行为对我来说似乎完全合理。
var converter = TypeDescriptor.GetConverter(typeof(bool?));
bool? nullableBool1 = converter.ConvertFrom(string.Empty); // returns null
bool? nullableBool2 = converter.ConvertFrom("true"); // returns true
bool? nullableBool3 = converter.ConvertFrom("false"); // returns false
bool? nullableBool4 = converter.ConvertFromString(string.Empty); // returns null
bool? nullableBool5 = converter.ConvertFromString("true"); // returns true
bool? nullableBool6 = converter.ConvertFromString("false"); // returns false
Run Code Online (Sandbox Code Playgroud)
从@C.Evenhuis 的评论来看,我认为这是有问题的行为。
var converter = TypeDescriptor.GetConverter(typeof(bool?));
var string1 = converter.ConvertToString(null); // returns ""
var string2 = converter.ConvertToString(true); // returns "true"
var string3 = converter.ConvertToString(false); // returns "false"
Run Code Online (Sandbox Code Playgroud)
ConvertToString正在做一些我觉得非常好的事情。如果您注意到,var isNullAString = null is string请返回false!对我来说,将 null 转换为空字符串更有意义,即使这不是您所期望的。
至于你问题中最后一个未解决的部分..
也许我错了,但我希望 IsValid 方法在值无法转换时返回 false,否则返回 true,但显然空字符串和 NullableConverter 的情况并非如此(对于其他可空类型也可以观察到相同的行为) 。
我相信上面的评论已经对此做出了令人满意的回答,其中指出
IsValid 方法用于验证类型内的值,而不是确定值是否可以转换为给定类型。例如,IsValid 可用于确定给定值对于枚举类型是否有效。
| 归档时间: |
|
| 查看次数: |
1075 次 |
| 最近记录: |