如何实际使用TypeConverter以及它与System.Convert.ToXXX()

时间:2018-03-26 08:37:48

标签: c# typeconverter

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

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

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

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

2 个答案:

答案 0 :(得分:5)

枚举仍然是自定义类型,仍然可以包含[TypeConverter]

等属性

只有少数API使用TypeConverter;特别是,这意味着System.ComponentModel,这就是PropertyGrid之类的东西,所以:你不会自动地到处获取它,但在某些情况下它仍然有用。获得转换器的主要方式是:

var conv = TypeDescriptor.GetConverter(obj);

允许它通过ICustomTypeDescriptor / TypeDescriptor处理属性(您已找到),TypeDescriptor.GetProviderTypeDescriptor.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);
    }
}

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

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

答案 1 :(得分:0)

我无法使用TypeConverter,但您可以直接从枚举中获取名称列表:

List<string> pageSizes = Enum.GetNames(typeof(PageSize)).ToList();

从名称/字符串表示中获取枚举值:

this.PageSize = (PageSize)Enum.Parse(typeof(PageSize), "A4")