gpt4 book ai didi

c# - TypeConverter 行为不一致?

转载 作者:可可西里 更新时间:2023-11-01 03:02:28 24 4
gpt4 key购买 nike

我正在开发一个 IValueConverter 实现,它可以转换 bool? 值。为了通用性,我决定使用 TypeConverter 将输入值转换为 bool?。因为它的主要目的是用作 XAML 绑定(bind)的转换器,所以我想避免抛出异常,因为它会导致 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 不是这种情况(对于其他可为 null 的类型可以观察到相同的行为)。

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

编辑

检查 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);
}

在我的例子中,simpleTypeConverterBooleanConverter 类型,可以理解的是,它为 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 结果无一异常(exception)。

虽然知道了这种行为的原因,但问题仍然存在 - 这是一种疏忽,还是打算以这种方式工作?我已经提交了 bug report并将发布任何结论。

最佳答案

不同的人在其中一些情况下的期望可能不一样,但对我来说,框架在这种情况下给出的行为似乎是合理的。

例如:在以下情况下,这种行为对我来说似乎是完全合理的。

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 转换为空字符串更有意义,即使这不是您所期望的。

关于您问题中最后 Unresolved 部分..

Perhaps I'm wrong, but I'd expect the IsValid method to return false whenever a value cannot be converted and true otherwise, but clearly that's not the case with an empty string and NullableConverter (same behavior can be observed for other nullable types).

我相信这在上面的评论中得到了令人满意的回答,其中指出

The IsValid method is used to validate a value within the type rather than to determine if value can be converted to the given type. For example, IsValid can be used to determine if a given value is valid for an enumeration type.

关于c# - TypeConverter 行为不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30417509/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com