C# 如何实际使用TypeConverter以及它与System.Convert.ToXXX()有何不同

C# 如何实际使用TypeConverter以及它与System.Convert.ToXXX()有何不同,c#,typeconverter,C#,Typeconverter,我一直在寻找一种更直观的方法来在C#中的数据类型之间进行转换(就像从枚举到字符串),因此我偶然发现了TypeConverter类。我已经阅读了关于如何创建一个的文档,它看起来相当简单,只需使用一些自定义转换逻辑覆盖TypeConverter中的一些方法,就可以了 然而,现在我已经创建了这个转换器,我还不知道如何实际使用它。我找到的每一个资源都简单地解释了如何创建一个,我所看到的实际使用它的唯一参考是用[TypeConverter(typeof(MyConverter))]装饰我的类型类。问题是我

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

然而,现在我已经创建了这个转换器,我还不知道如何实际使用它。我找到的每一个资源都简单地解释了如何创建一个,我所看到的实际使用它的唯一参考是用
[TypeConverter(typeof(MyConverter))]
装饰我的类型类。问题是我实际上没有类型类,我转换的类型是枚举和字符串,所以我不知道我应该把类型转换器放在哪里

假设我的类型是一个自定义类,我把装饰放在它定义的类上,那么我如何转换类型呢?我是否只是在任何我想要的地方使用类型作为字符串,转换器将神奇地完成其工作而不被询问,或者我是否需要以某种方式提示它。是否存在可以使用类型转换器的范围,或者是否可以在类型所在的任何位置访问它


我有点希望它能像System.Convert一样工作,但事实似乎并非如此。

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

只有少数API使用
类型转换器
;特别是,这意味着
System.ComponentModel
,这是像
PropertyGrid
这样的东西的驱动力,因此:您不会自动地在任何地方都获得它,但在某些情况下它仍然很有用。获得转换器的主要预期方法是:

var conv = TypeDescriptor.GetConverter(obj);
它允许它通过
TypeDescriptor.GetProvider
/
TypeDescriptor.AddProvider
处理属性(您已经找到),还可以使用
ICustomTypeDescriptor
TypeDescriptor
。它是一个非常混乱但灵活的动态描述数据的模型

然而,在大多数情况下,
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.上的方法非常不同,因为它不是一个可扩展的模型<代码>系统.ComponentModel可以在运行时进行调整,并与对象级别(而不是类型级别)描述自身的对象一起使用。它的主要用途是用于
DataTable
,这样一行就可以像它有为每列命名的属性一样-通过
PropertyDescriptor
,而不是
PropertyInfo
(反射)。

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

List pageSizes=Enum.GetNames(typeof(PageSize)).ToList()

要从其名称/字符串表示形式获取枚举值,请执行以下操作:


this.PageSize=(PageSize)Enum.Parse(typeof(PageSize),“A4”)

从未使用过它,但还有一个更具体的类继承自
TypeConverter
@Corak
EnumConverter
自动用作所有枚举的默认转换器,IIRCI猜测是一个“简单的”
enumValue.ToString()
枚举类型枚举值;TryParse(“StringValue”,out EnumValue)不够?TypeConverter为Visual Studio中的PropertyGrid类和Properties窗口提供电源。它的主要工作是将一个类型转换为对人类有意义的字符串。Winforms是其最大的客户。它在您自己的代码中也非常方便,但您必须了解它的域。如果类型是您自己的,而不是框架中的类型,并且您不使用严格的类型输入或不关心本地化,那么编写自己的类型转换器很少会让您领先,它只是增加了一层您不需要的复杂性。
enumValue.ToString()
实际上可以工作,这就是我在这种情况下所需要的。我甚至没有想过尝试它,因为我的印象是枚举在运行时只能作为静态整数列表使用。所以这听起来似乎与PropertyGrid和WinForms有着非常密切的关系?为了支持WPF,我跳过了WinForms,但是TypeConverter在任何方面都可以与WPF valueconverter相媲美吗?@Olli你是对的,WinForms和TypeConverter之间有着很强的关系。我对WPF了解不多,所以我不能自信地评论,但我怀疑它们是类似的概念,具有完全不相关的实现。