2009-06-05 14 views
7

Tôi muốn triển khai chức năng chuyển đổi loại thời gian chạy theo mục đích chung sử dụng .Net TypeConverters để thực hiện chuyển đổi.Cách tra cứu và gọi .Net TypeConverter cho một loại cụ thể?

Có ai biết cách tìm kiếm và gọi một TypeConverter cho một loại cụ thể không?

Xem xét việc này C# Ví dụ:

// 
// Convert obj to the type specified by 'toType'. 
// 
object ConvertTo(object obj, Type toType) 
{ 
    if (TypeIsEqualOrDerivesFrom(obj.GetType(), toType)) <-- I know how to implement this. 
    { 
     // The type of obj is the same as the type specified by 'toType' or 
     // the type of obj derives from the type specified by 'toType'. 
     return obj; 
    } 

    if (TypeConverterExists(obj.GetType(), toType) <-- How do I implement this? 
    { 
     // There exists a type convertor that is capable of converting from 
     // the type of obj to the type specified by 'toType'. 
     return InvokeTypeConverter(obj, toType); <-- How do I implement this? 
    } 

    throw new TypeConversionFailedException(); 
} 
+0

Don không sử dụng 'dotnet' cho thẻ. –

Trả lời

31
TypeConverter converter = TypeDescriptor.GetConverter(sourceType); 
    if(converter.CanConvertTo(destinationType)) { 
     return converter.ConvertTo(obj, destinationType); 
    } 
    converter = TypeDescriptor.GetConverter(destinationType); 
    if(converter.CanConvertFrom(sourceType)) { 
     return converter.ConvertFrom(obj); 
    } 

Bạn cũng có thể nhìn vào Convert.ChangeType(obj, destinationType)

+2

Tôi không nghĩ Convert.ChangeType sử dụng trình chuyển đổi loại. – Patrik

+0

Ngoài ra, hãy xem Enum.ToObject nếu bạn cần chuyển đổi loại tích phân thành loại được liệt kê thực tế. –

1

Ngoài câu trả lời của Marc, bạn có thể xem xét rằng ViewState ASP.NET của hiện một chức năng tương tự như những gì bạn đang yêu cầu. Nó cố gắng tìm chuyển đổi hiệu quả nhất.

Có thể đáng xem tại this page và có thể cả this one.

9

Đây là mã được sử dụng trong một trong các ứng dụng hiện có của chúng tôi ... không chắc chắn nếu nó là lý tưởng nhưng nó hoạt động tốt cho chúng tôi.

/// <summary> 
/// Attempts to convert a value using any customer TypeConverters applied to the member 
/// </summary> 
/// <param name="value">Object containing the value to be assigned</param> 
/// <param name="member">Member to be assigned to</param> 
/// <returns><paramref name="value"/> converted to the appropriate type</returns> 
public static Object CustomTypeConversion (object value, MemberInfo member) 
{ 
    if (value == null || value == DBNull.Value) 
     return value; 

    if (member == null) 
     throw new ArgumentNullException (); 

    List<TypeConverter> converters = GetCustomTypeConverters (member); 

    foreach (TypeConverter c in converters) 
    { 
     if (c.CanConvertFrom (value.GetType ())) 
      return c.ConvertFrom (value); 
    } 

    if (member is PropertyInfo) 
    { 
     PropertyInfo prop = member as PropertyInfo; 
     return ConvertToNative(value , prop.PropertyType); 
    } 
    return ConvertToNative (value, member.MemberType.GetType ()); 
} 

/// <summary> 
/// Extracts and instantiates any customer type converters assigned to a 
/// derivitive of the <see cref="System.Reflection.MemberInfo"/> property 
/// </summary> 
/// <param name="member">Any class deriving from MemberInfo</param> 
/// <returns>A list of customer type converters, empty if none found</returns> 
public static List<TypeConverter> GetCustomTypeConverters (System.Reflection.MemberInfo member) 
{ 
    List<TypeConverter> result = new List<TypeConverter>(); 

    try 
    { 
     foreach (TypeConverterAttribute a in member.GetCustomAttributes(typeof(TypeConverterAttribute) , true)) 
     { 
      TypeConverter converter = Activator.CreateInstance(Type.GetType(a.ConverterTypeName)) as TypeConverter; 

      if (converter != null) 
       result.Add(converter); 
     } 
    } 
    catch 
    { 
     // Let it go, there were no custom converters 
    } 

    return result; 
} 

/// <summary> 
/// Attempts to cast the incoming database field to the property type 
/// </summary> 
/// <param name="value">Database value to cast</param> 
/// <param name="castTo">Type to cast to</param> 
/// <returns>The converted value, if conversion failed the original value will be returned</returns> 
public static object ConvertToNative (object value , Type castTo) 
{ 
    try 
    { 
     return Convert.ChangeType(value , castTo , System.Threading.Thread.CurrentThread.CurrentCulture); 
    } 
    catch 
    { 
     return value; 
    } 
} 

Chỉ cần gọi phương thức CustomTypeConversion và lập tức bạn đi ... có lẽ là một chút nhiều hơn bạn cần nhưng là triệt để không phải là một tội phạm (hoặc là nó?).

+3

Lưu ý rằng việc triển khai TypeConverter có thể được thêm vào lúc chạy (thông qua TypeDescriptor) - và khung tiêu chuẩn sẽ chọn điều đó - nhưng sự phản ánh (ở trên) * sẽ không * nhận các bổ sung đó; System.ComponentModel được thiết kế rất linh hoạt trong thời gian chạy ... –

+0

Ah, tốt nhất ... vấn đề đó đã đến với chúng tôi (chưa) - mã này đã được xung quanh ứng dụng của chúng tôi trong một thời gian; thật tốt khi có một bộ mắt mới. Cảm ơn! –

+0

Thành thật mà nói, trong hầu hết các trường hợp, bạn sẽ không bao giờ thấy sự khác biệt ... nó không phải là * phổ biến mà mọi người bắt đầu thêm bộ chuyển đổi/bộ mô tả thời gian chạy. Nhưng nó là có thể (tôi đã có một ví dụ về stackoverflow một nơi nào đó ...) –

1

Tôi không biết làm thế nào mạnh mẽ đó là, nhưng đôi khi tôi sử dụng mã này để chuyển đổi loại hình chung:

public T ConvertTo<T>(object value) 
{ 
    return (T)Convert.ChangeType(value, typeof(T)); 
} 

Tôi không biết nếu TypeConverters sử dụng phương pháp ChangeType ...

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