2009-06-05 2 views
7

.Net TypeConverters를 사용하여 변환을 수행하는 범용 런타임 유형 변환 함수를 구현하고 싶습니다.특정 유형의 .Net TypeConverter를 검색하고 호출하는 방법은 무엇입니까?

누구든지 특정 유형의 TypeConverter를 검색하고 호출하는 방법을 알고 있습니까? 당신은 ASP.NET의 ViewState에 당신이 무엇을 유사한 기능을한다는 것을 고려해 볼 수 있습니다

// 
// 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

돈 태그에 'dotnet'을 사용하지 마십시오. –

답변

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

당신은 또한 마크의 대답에 추가 Convert.ChangeType(obj, destinationType)

+2

Convert.ChangeType은 형식 변환기를 사용한다고 생각하지 않습니다. – Patrik

+0

또한 실제 열거 형으로 정수 유형을 변환해야하는 경우 Enum.ToObject를 확인하십시오. –

1

볼 수 있습니다 :

이 C# 예제를 고려 할 것을 요구합니다. 가장 효율적인 전환을 찾습니다.

this page 및 아마도 this one을 살펴볼 가치가 있습니다.

9

다음은 기존 앱 중 하나에 사용 된 코드입니다. 이상적인 버전인지는 확실하지 않지만 잘 작동합니다.

/// <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; 
    } 
} 

그냥 CustomTypeConversion 메소드를 호출 멀리 당신은 당신이 필요로하는 것보다 아마 ... 조금 더 가야하지만 철저한되는 것은 범죄가 아니다 (또는 무엇입니까?).

+3

TypeConverter 구현은 런타임시 (TypeDescriptor를 통해) 추가 될 수 있으며 표준 프레임 워크는이를 선택합니다. 그러나 위의 반영 (*)은 이러한 추가 사항을 선택하지 않습니다. System.ComponentModel은 런타임시 매우 융통성있게 디자인되었습니다 ... –

+0

아, 좋은 점 ... 그 문제는 우리를 위해 (아직) 왔습니다 -이 코드는 잠시 동안 우리의 응용 프로그램을 둘러 봤습니다. 신선한 눈을 가지고 리뷰하는 것이 좋습니다. 감사! –

+0

솔직히 말해서, 대부분의 경우에 차이점을 보지 못할 것입니다 ... 사람들이 런타임 변환기/설명자를 추가하기 시작한 것은 아닙니다. 그러나 그것은 가능합니다. (어딘가에 stackoverflow에 대한 예제가 있습니다 ...) –

1

나는 그것이 얼마나 강력한 모르겠지만, 가끔 제네릭 형식 변환이 코드를 사용 :

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

내가 모르는의 ChangeType 방법을 사용 TypeConverters 경우 ...

관련 문제