如何实际使用TypeConverter,它与System.Convert.ToXXX()的区别

Oll*_*lli 3 c# typeconverter

我一直在寻找一种更直观的方式来转换C#中的数据类型(比如枚举到字符串)所以我偶然发现了TypeConverter类.我已经阅读了有关如何创建一个文档的文档,它看起来相当简单,只需使用一些自定义转换逻辑覆盖TypeConverter中的一些方法并完成.

但是,我已经无法弄清楚如何实际使用这个转换器,因为我已经创建了它.我发现的每一个资源都只是解释了如何创建一个,而我见过的实际使用它的唯一参考就是装饰我的类型类[TypeConverter(typeof(MyConverter))].问题是我实际上没有类型类,我的类型im转换为/来自枚举和字符串,所以我不知道我应该把TypeConverter放在哪里.

假设我的类型是自定义类,并且我将装饰放在其定义的类上,我将如何转换类型?我只是在任何地方使用该类型作为字符串,转换器将神奇地完成其工作而不被问及我是否需要以某种方式提示它.是否有可以使用类型转换器的范围,或者它可以在类型的任何地方访问?

我有点期待它像System.Convert一样工作,但似乎并非如此.

Mar*_*ell 5

枚举仍然是自定义类型,并且仍然可以具有诸如的属性[TypeConverter].

只使用少量的API TypeConverter; 特别是,这意味着System.ComponentModel,这就是驱动类似的东西PropertyGrid,因此:你不会自动地到达任何地方,但它在某些情况下仍然有用.获得转换器的主要方式是:

var conv = TypeDescriptor.GetConverter(obj);
Run Code Online (Sandbox Code Playgroud)

这使得它能够与属性(你已经找到)工作,也ICustomTypeDescriptorTypeDescriptor通过TypeDescriptor.GetProvider/ TypeDescriptor.AddProvider.这是一个非常混乱但灵活的动态描述数据模型.

但是,在大多数情况下,TypeConverter通常不是实现方法的方式.作为一个勉强工作的例子:

using System;
using System.ComponentModel;
using System.Globalization;

static class P
{
    static void Main()
    {
        var foo = Foo.Gamma;
        var converter = TypeDescriptor.GetConverter(typeof(Foo));
        string s = converter.ConvertToString(foo);
        Console.WriteLine(s);
    }
}

[TypeConverter(typeof(FooConverter))]
public enum Foo
{
    Alpha, Beta, Gamma
}
class FooConverter : TypeConverter
{
    public override object ConvertTo(ITypeDescriptorContext context,
        CultureInfo culture, object value, Type destinationType)
    {
        // write it backwards, because: reasons
        if (destinationType == typeof(string)) {
            var s = value.ToString();
            char[] c = s.ToCharArray();
            Array.Reverse(c);
            return new string(c);
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如前所述,当与PropertyGrid其他UI元素混合使用时,它可能更有意义.

它与方法非常不同Convert.*,因为它不是可扩展的模型.System.ComponentModel可以在运行时调整,并与对象级别(不是类型级别)描述自身的对象一起使用.这种情况的主要用途是,例如DataTable,一行可以表现为它具有为每列命名的属性 - 通过PropertyDescriptor而不是PropertyInfo(反射).