I've been looking for a more intuitive way of converting between datatypes in C# (like an enum to a string) So i stumbled upon the TypeConverter class. I've read the documentation on how to create one, and it seems fairly straightforward, just override a few methods from TypeConverter with some custom conversion logic and done.
However, ive been unable to figure out how to actually use this converter now that i've created it. every resource I've found simply explains how to create one, and the only reference ive seen to actually using it is decorating my type class with [TypeConverter(typeof(MyConverter))]
. The problem is I dont actually have a type class, my type im converting to/from is an enum and string, so i have no idea where im supposed to put the TypeConverter.
Hypothetically if my type was a custom class, and I put the decoration just on the class where its defined, how would I then convert the type? Do I just use the type as a string wherever i want and the converter will magically do its work without being asked or do i need to prompt it somehow. Is there a scope within which I can use the type converter or is it accessible anywhere that the type is?
I was kind of expecting this to work like System.Convert, but that doesnt seem to be the case.
An enum is still a custom type and can still have attributes such as [TypeConverter]
.
Only a small number of APIs use TypeConverter
; in particular, this means System.ComponentModel
, which is what drives things like PropertyGrid
, so: you don't get it everywhere automatically, but it can still be useful in some cases. The main intended way of getting the converter is:
var conv = TypeDescriptor.GetConverter(obj);
which allows it to work with attributes (which you've found), but also ICustomTypeDescriptor
and TypeDescriptor
, via TypeDescriptor.GetProvider
/ TypeDescriptor.AddProvider
. It is a very confusing but flexible model for dynamically describing data.
In most scenarios, however, TypeConverter
is not usually the way to implement things. As a barely working example:
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);
}
}
However, it probably makes more sense - as noted previously - when mixed with things like PropertyGrid
or other UI elements.
It is very different to the methods on Convert.*
, as that is not an extensible model. System.ComponentModel
can be tweaked at runtime, and used with objects that at the object level (not the type level) describe themselves. The main usage of this was for things like DataTable
, so that a row can act as though it has properties named for each column - via PropertyDescriptor
rather than PropertyInfo
(reflection).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With