C#如何实现类型转换器

17

我在C#中难以实现一个简单的类型转换器。我遵循了这个指南https://msdn.microsoft.com/en-us/library/ayybcxe5.aspx

这是我的类:

public class TestClass: TypeConverter
{
        public string Property1{ get; set; }
        public int Property2 { get; set; }
        public TestClass(string p1, int p2)
        {
            Property1= p1;
            Property2 = p2;
        }
        public override bool CanConvertFrom(ITypeDescriptorContext context,
        Type sourceType)
        {
            if (sourceType == typeof(string)) {
                 return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
        public override object ConvertFrom(ITypeDescriptorContext context,
         CultureInfo culture, object value)
        {
              if (value is string) {
                    return new TestClass ("", Int32.Parse(value.ToString()));
              }
              return base.ConvertFrom(context, culture, value);
        }
        public override object ConvertTo(ITypeDescriptorContext context,
        CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string)) {
               return "___"
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
 }

目前我所关注的只是以下情况:将字符串"1231"转换为整数后传入TestClass("", Int32.Parse(value.ToString()));

下面是导致异常的代码:

TypeConverter converter=TypeDescriptor.GetConverter( typeof(TestClass));
Object lalala = converter.ConvertFromString("234");

这段代码抛出了NotSupportedException异常,但我不知道为什么

2个回答

35
提供的代码有些混乱,还缺少一些重要的东西。下面是一个实现,将自定义类 CrazyClass 转换为字符串并从字符串转换回来。 CrazyClassTypeConverter
public class CrazyClassTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var casted = value as string;
        return casted != null
            ? new CrazyClass(casted.ToCharArray())
            : base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        var casted = value as CrazyClass;
        return destinationType == typeof (string) && casted != null
            ? String.Join("", casted.Charray)
            : base.ConvertTo(context, culture, value, destinationType);
    }
}

CrazyClass(疯狂类)

(请注意该类被TypeConverterAttribute修饰)

[TypeConverter(typeof(CrazyClassTypeConverter))]
public class CrazyClass
{
    public char[] Charray { get; }

    public CrazyClass(char[] charray)
    {
        Charray = charray;
    }
}

使用方法

var crazyClass = new CrazyClass(new [] {'T', 'e', 's', 't'});
var converter = TypeDescriptor.GetConverter(typeof(CrazyClass));

//this should provide you the string "Test"        
var crazyClassToString = converter.ConvertToString(crazyClass); 

//provides you an instance of CrazyClass with property Charray set to {'W', 'h', 'a', 't' } 
var stringToCrazyClass = converter.ConvertFrom("What"); 

嗨,但stringToCrazyClass是“object”而不是CrazyClass类型,如何将其转换为CrazyClass类型? - alhpe
@alhpe 你只需要将它转换为CrazyClass即可。 - Knight0fDragon
2
char + array = charraay... 你疯了 CrazyClass - Efreeto

13

您需要将此转换器附加到带有TypeConverter属性的类上。
TypeDescriptor.GetConverter获取类的附加转换器。

最好将类拆分:

[TypeConverter(typeof (TestClassConverter))]
public class TestClass
{
    public string Property1 { get; set; }
    public int Property2 { get; set; }
    public TestClass(string p1, int p2)
    {
        Property1 = p1;
        Property2 = p2;
    }
}

[TypeConverter(typeof (TestClassConverter))]
public class TestClassConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context,
    Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }
    public override object ConvertFrom(ITypeDescriptorContext context,
     CultureInfo culture, object value)
    {
        if (value is string)
        {
            return new TestClass("", Int32.Parse(value.ToString()));
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context,
    CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string)) { return "___"; }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

27
你为什么在类和转换器上都添加了TypeConverterAttribute - Mladen B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接