2013-09-26 22 views
6

Tôi đang làm việc trên một ứng dụng kiểu ETL tạo ra các thực thể từ tệp dữ liệu csv. Một lĩnh vực đặc biệt - một lĩnh vực boolean - đang chứng minh khó khăn để làm việc với vì hệ thống cung cấp giải thích riêng của họ về một bool như true, false, yes, no, 1, 0 hoặc thậm chí -1, v.v.Làm cách nào để ghi đè trình chuyển đổi loại NET?

Sử dụng mặc định loại chuyển đổi hầu hết các thử nghiệm thất bại:

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); 

những gì tôi muốn làm là ghi đè lên System.ComponentModel.BooleanConverter mặc định vì vậy mà tôi có thể cung cấp phân tích cú pháp của riêng tôi để xử lý một cách chính xác ở trên. Bất kỳ ý tưởng làm thế nào để làm điều này?

Điều này post bởi Scott Hanselman chạm vào việc tạo trình chuyển đổi loại nhưng tôi muốn ghi đè cài đặt mặc định.

Để tham khảo, đây là triển khai trình trích xuất đối tượng của tôi.

public static TEntity ExtractEntity<TEntity>(Dictionary<string, string> row) where TEntity : class 
{ 
    var entity = Activator.CreateInstance<TEntity>(); 
    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; 
} 

Về cơ bản nó liệt kê một TEntity nhất định và cho từng lĩnh vực công ty không giành mục của từ điển bằng chìa khóa của mình và cố gắng để chuyển nó sang dạng cơ bản của lĩnh vực. Nó hoạt động tốt ngoại trừ bools.

+2

Bạn có thể đăng ký TypeConverter tùy chỉnh cho bools bằng thuộc tính, sau đó sử dụng 'TypeDescriptor.GetConverter (info.PropertyType)', sẽ luôn trả về TypeConverter của bạn theo mặc định. Sử dụng bộ chuyển đổi kết quả để chuyển đổi giá trị của bạn thành 'info.PropertyType' trước khi sử dụng. –

+0

bản sao có thể có của [Có thể ghi đè bộ mô tả kiểu cho loại .net hiện có không?] (Http://stackoverflow.com/questions/4713177/is-it-possible-to-override-the-type-descriptor- cho một hiện có-net-type) –

Trả lời

4

Nhờ Asad Tôi tạo ra một phong tục 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); 
    } 
} 

Và đăng ký tại khởi động của chương trình:

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

Bây giờ với mã vắt sửa đổi, cho mỗi tài sản loại chuyển đổi chính xác được sử dụng. Thông thường, đây sẽ là một trong các trình chuyển đổi tích hợp, nhưng do việc đăng ký BoolTypeConverter cho kiểu boolean, nên nó được sử dụng thay thế.

public static TEntity ExtractEntity<TEntity>(Dictionary<string, string> row) where TEntity : class 
{ 
    var entity = Activator.CreateInstance<TEntity>(); 
    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; 
} 
+0

Vì câu trả lời này giải quyết được vấn đề trong câu hỏi của bạn, bạn nên đánh dấu nó là câu trả lời được chấp nhận bằng cách nhấp vào dấu kiểm bên cạnh câu trả lời đó. Bằng cách đó mọi người có thể nói nhanh rằng vấn đề đã được giải quyết. –

+0

slick! Điều này có ghi đè lên chuyển đổi loại mặc định không? Hay đơn giản là thêm một cách chuyển đổi khác. Tôi hy vọng nó sẽ thêm một cách khác để chuyển đổi – matrixugly

Các vấn đề liên quan