- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在开发一个 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);
}
在我的例子中,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
结果无一异常(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/
似乎 TypeConverter.IsValid() 使用了当前的线程文化,但 TypeConverter.ConvertFrom() 没有。 这使得将 TypeConverter.IsValid()
我已将 Room 集成到我的项目中。在这个项目中,一些类在 Kotlin 中,一些在 Java 中。在我使用 Android Studio Ctrl+Alt+Shift+K 组合将我的 Java 文件
我在实现 Room 的类型转换器时出错。 error: Cannot figure out how to save this field into database. You can consider
这很烦人: 我想要这个: 所以我写了一个TypeConverter: public class PenConverter : TypeConverter {
我正在使用 4.0,我正在尝试通过开发一些用于类型转换的辅助方法来让我的生活更轻松。以下方法运行良好。它将从任何字符串转换为其他数据类型。 System.ComponentModel; public
我正在尝试向我的房间数据库中添加一个“图片”字段,其中包含一个名为 MyPicture 的自定义对象,该对象具有以下属性。 private String id; private User user;
我有一个简单的 TypeConverter将逗号分隔的字符串转换为 IEnumerable在调用我的 API 端点时缩短 url。 因此我有一个在客户端设置并传递给服务器的请求对象。所以,在服务器上它
为什么那些返回 true: TypeDescriptor.GetConverter(typeof(double)).CanConvertTo(typeof(double)); TypeDesc
我想创建一个 TypeConverter对于通用类,像这样: [TypeConverter(typeof(WrapperConverter))] public class Wrapper { p
我正在开发一个 IValueConverter 实现,它可以转换 bool? 值。为了通用性,我决定使用 TypeConverter 将输入值转换为 bool?。因为它的主要目的是用作 XAML 绑定
我正在尝试编写这样的标记扩展: [MarkupExtensionReturnType(typeof(Length))] public class LengthExtension : MarkupExt
我正在寻找一种将附加信息传递给 TypeConverter 的方法,以便在不创建自定义构造函数的情况下为转换提供一些上下文。 传递的额外信息将是包含我正在转换的属性的原始对象(在编译时称为接口(int
我目前正在学习 Room Persistence,我只想问一下如何为自定义类创建 TypeConverter? Brand.kt @Parcelize @Entity(tableName = "bra
在我看来,与 TypeConverter 相比,实现隐式运算符非常容易,因此我假设它们不等效,因为框架中普遍存在 TypeConverters(请参阅扩展 FrameworkElement 的任何内容
我有一个 PowerShell 类,我想自动从 string 转换它。 所以我这样定义了一个TypeConverter: class StringToAcmeStateConverter :
到目前为止,为了存储在房间数据库中,我一直在为每个类使用类型转换器。像这样: @SerializedName("sidebar") @Expose @TypeConverters(SidebarCon
我有一个具有以下属性的类: [TypeConverter(typeof(SomeNameEnumValueConvert))] public Example ExampleName { get; se
使用 CsvHelper,当我想要一个自定义解析器时(例如,我想要一个输入字符串为“f”的 MyBooleanConverter 将为 false,“t”将为是真实的”)。但是对于每个类我都必须编写映
我正在研究 XAML 中声明的泛型类型的初始化成员。这是针对 (reduced) generics support在 WPF 4 和 future 的 Silverlight 中。 (我已经在 VS2
我已按照有关如何为自定义类型添加 TypeConverter 的房间文档进行操作,但我的实体类仍然出现错误。我想简单地将 Category 枚举转换为 String,以便房间数据库了解如何存储它。下面
我是一名优秀的程序员,十分优秀!