C# How to Implement Type Converter

C# How to Implement Type Converter

I am struggling to implement a simple Type converter in C#. I followed this guide

Here is my class :

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

I do the following TestClass ("", Int32.Parse(value.ToString())); as for now I am only interested in such case as "1231" -> new TestClass("", 1231)

And here goes the code that gives me an exception;

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

This code throws NotSupportedException but I don't get why

2 Answers

The code provided is a bit mixed up and it's missing some important stuff. Following, an implementation that converts a custom class CrazyClass from and to string.

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

(note that the class is decorated with TypeConverterAttribute)

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

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

Usage

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"); 
3

You have to attach this converter to a class with the TypeConverter attribute.
TypeDescriptor.GetConverter Get the attached converter of the class.

You better split the classes:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.