如何覆盖NET类型转换器?

我正在开发一个ETL类型的应用程序,它从csv数据文件创建实体。 特别是一个字段 – 一个布尔字段 – certificate难以使用,因为系统提供了他们自己对bool的解释,如true,false,yes,no,1,0,甚至-1等。

使用默认类型转换器,大多数测试失败:

var b1 = Convert.ChangeType("true", TypeCode.Boolean, CultureInfo.InvariantCulture); var b2 = Convert.ChangeType("false", TypeCode.Boolean, CultureInfo.InvariantCulture); var b3 = Convert.ChangeType("True", TypeCode.Boolean, CultureInfo.InvariantCulture); var b4 = Convert.ChangeType("False", TypeCode.Boolean, CultureInfo.InvariantCulture); var b5 = Convert.ChangeType("TRUE", TypeCode.Boolean, CultureInfo.InvariantCulture); var b6 = Convert.ChangeType("FALSE", TypeCode.Boolean, CultureInfo.InvariantCulture); // All below fail var b7 = Convert.ChangeType("yes", TypeCode.Boolean, CultureInfo.InvariantCulture); var b8 = Convert.ChangeType("no", TypeCode.Boolean, CultureInfo.InvariantCulture); var b9 = Convert.ChangeType("Yes", TypeCode.Boolean, CultureInfo.InvariantCulture); var b10 = Convert.ChangeType("No", TypeCode.Boolean, CultureInfo.InvariantCulture); var b11 = Convert.ChangeType("YES", TypeCode.Boolean, CultureInfo.InvariantCulture); var b12 = Convert.ChangeType("NO", TypeCode.Boolean, CultureInfo.InvariantCulture); var b13 = Convert.ChangeType("1", TypeCode.Boolean, CultureInfo.InvariantCulture); var b14 = Convert.ChangeType("0", TypeCode.Boolean, CultureInfo.InvariantCulture); 

我想要做的是覆盖默认的System.ComponentModel.BooleanConverter,以便我可以提供自己的解析器来正确处理上面的内容。 知道怎么做吗?

Scott Hanselman撰写的这篇文章涉及创建类型转换器,但我希望覆盖默认值。

这里参考我的实体提取器实现。

 public static TEntity ExtractEntity(Dictionary row) where TEntity : class { var entity = Activator.CreateInstance(); var entityType = typeof(TEntity); foreach (var info in entityType.GetProperties()) { try { info.SetValue( entity, Convert.ChangeType(row[info.Name], info.PropertyType, CultureInfo.InvariantCulture), null); } catch {} } return entity; } 

基本上它枚举给定的TEntity,并且对于每个公共字段,它通过其键获取字典的项目并尝试将其转换为字段的基础类型。 除了布尔之外,它运作良好。

感谢Asad,我创建了一个自定义的TypeConverter

 class BoolTypeConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof (bool)) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (value is string) { var s = value as string; if (string.IsNullOrEmpty(s)) return false; switch (s.Trim().ToUpper()) { case "TRUE": case "YES": case "1": case "-1": return true; default: return false; } } return base.ConvertTo(context, culture, value, destinationType); } } 

并在该计划的创业公司注册:

 TypeDescriptor.AddAttributes(typeof(Boolean), new TypeConverterAttribute(typeof(BoolTypeConverter))); 

现在使用修改后的提取器代码,对于每个属性,使用正确的类型转换器。 通常这将是内置转换器之一,但由于BoolTypeConverter注册了类型boolean,因此使用它。

 public static TEntity ExtractEntity(Dictionary row) where TEntity : class { var entity = Activator.CreateInstance(); var entityType = typeof(TEntity); foreach (var info in entityType.GetProperties()) { try { var converter = TypeDescriptor.GetConverter(info.PropertyType); if (!converter.CanConvertTo(info.PropertyType)) continue; info.SetValue(entity, converter.ConvertTo(row[info.Name], info.PropertyType)); } catch {} } return entity; }