我正在开发一个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
(其他可以为空的类型可以观察到相同的行为)。
这是一个错误还是设计选择?如果是后者,还有其他类似案例吗?
修改
检查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
语句,因此if(!preg_match("/" . preg_quote($citation_msg_string, "/") . "/", $file_contents))
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
结果没有例外。
知道这种行为的原因问题仍然存在 - 这是一种疏忽,还是打算以这种方式工作?我已经提交了source code,并会发布任何结论。
答案 0 :(得分:1)
在某些情况下,不同的人可能会有不同的看法,但对我来说,在这种情况下框架给出的行为似乎是合理的。
例如:在下列情况下,这种行为对我来说似乎是完全合理的。
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
来自@ 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"
ConvertToString
正在做一些我觉得非常好的事情。如果您注意,var isNullAString = null is string
会返回false
!对于我来说,将null转换为空字符串更有意义,即使这不是您所期望的。
关于你问题中最后一个未解决的部分..
也许我错了,但我希望IsValid方法在无法转换值时返回false,否则为true,但显然不是空字符串和NullableConverter的情况(其他情况可以观察到相同的行为)可空类型。
我相信这在上面的评论中得到了令人满意的回答,其中说明了
IsValid方法用于验证类型中的值,而不是确定是否可以将值转换为给定类型。例如,IsValid可用于确定给定值是否对枚举类型有效。
答案 1 :(得分:0)
你遇到问题的原因是因为String.Empty是一个类vs“”是一个文字。它是ReadOnly Varialble。这意味着它是一个类型为字符串的NULL变量。