TypeConverter行为不一致?

时间:2015-05-23 20:56:26

标签: c# typeconverter

我正在开发一个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(其他可以为空的类型可以观察到相同的行为)。

这是一个错误还是设计选择?如果是后者,还有其他类似案例吗?

修改

检查NullableConverterIsValid我认为我找到了这种行为的原因。这是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,并会发布任何结论。

2 个答案:

答案 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变量。