C# 如何查找和调用特定类型的 .Net TypeConverter?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/956076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:13:04  来源:igfitidea点击:

How to lookup and invoke a .Net TypeConverter for a particular type?

c#.nettype-conversion

提问by Ashley Davis

I would like to implement a general purpose runtime type conversion function that makes use .Net TypeConverters to do the conversion.

我想实现一个通用的运行时类型转换函数,它使用 .Net TypeConverters 进行转换。

Does anyone know how to how to look up and invoke a TypeConverter for a particular type?

有谁知道如何查找和调用特定类型的 TypeConverter?

Consider this C# example:

考虑这个 C# 示例:

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

回答by Marc Gravell

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

You could also look at Convert.ChangeType(obj, destinationType)

你也可以看看 Convert.ChangeType(obj, destinationType)

回答by Jeff Moser

In addition to Marc's answer, you might consider that ASP.NET's ViewState does a similar function to what you're asking to do. It tries to find the most efficient conversion.

除了 Marc 的回答之外,您可能会认为 ASP.NET 的 ViewState 执行的功能与您要求执行的功能类似。它试图找到最有效的转换。

It might be worth a look at this pageand possibly this onetoo.

可能值得一看这个页面,也可能是这个页面

回答by Steve Dignan

Here's the code used in one of our existing apps... not sure if it's ideal but it works well for us.

这是我们现有应用程序之一中使用的代码……不确定它是否理想,但对我们来说效果很好。

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

Just call the CustomTypeConversion method and away you go... probably a littlemore than you need but being thorough isn't a crime (or is it?).

只需调用CustomTypeConversion方法和远离你去...大概一点比你更需要但作为彻底的不是罪(是吗?)。

回答by Thomas Levesque

I don't know how robust it is, but I sometimes use this code for generic type conversion :

我不知道它有多健壮,但我有时会使用此代码进行泛型类型转换:

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

I don't know if the ChangeType method use TypeConverters...

我不知道 ChangeType 方法是否使用 TypeConverters ...