Enum description TypeConverter

From this article you can learn how to define and use enum description type converter so sytem will know how to handle enum to string and string to enum values (very helpful in PropertyGrid for example).

Implementation is available both in C# and VB.Net languages.

Implementation

Below you can find implementation we use in Karmian Framework as enum description type converter. It can be easily extended to work also as localizable enum description type converter - Description attribute can be used as a key of localized resource.

EnumDescriptionTypeConverter class

using System;
using System.ComponentModel;
using System.Globalization;
 
namespace Karmian.Core.TypeConverters
{
  public class EnumDescriptionTypeConverter : EnumConverter
  {
    public EnumDescriptionTypeConverter(Type type) : base(type)
    {
    }
 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
      return sourceType == typeof(string) || TypeDescriptor.GetConverter(typeof(Enum)).CanConvertFrom(context, sourceType);
    }
 
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
      if (value is string)
        return GetEnumValue(EnumType, (string) value);
      if (value is Enum)
        return GetEnumDescription((Enum) value);
      return base.ConvertFrom(context, culture, value);
    }
 
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
      return value is Enum && destinationType == typeof(string)
          ? GetEnumDescription((Enum)value)
          : (value is string && destinationType == typeof(string)
            ? GetEnumDescription(EnumType, (string)value)
            : base.ConvertTo(context, culture, value, destinationType));
    }
 
    public static string GetEnumDescription(Enum value)
    {
      var fieldInfo = value.GetType().GetField(value.ToString());
      var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
      return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
    }
 
    public static string GetEnumDescription(Type value, string name)
    {
      var fieldInfo = value.GetField(name);
      var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
      return (attributes.Length > 0) ? attributes[0].Description : name;
    }
 
    public static object GetEnumValue(Type value, string description)
    {
      var fields = value.GetFields();
      foreach (var fieldInfo in fields)
      {
        var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes.Length > 0 && attributes[0].Description == description)
          return fieldInfo.GetValue(fieldInfo.Name);
        if (fieldInfo.Name == description)
          return fieldInfo.GetValue(fieldInfo.Name);
      }
      return description;
    }
  }
}

Imports System.ComponentModel
Imports System.Globalization
 
Namespace Karmian.Core.TypeConverters
  Public Class EnumDescriptionTypeConverter
    Inherits EnumConverter
    Public Sub New(type As Type)
      MyBase.New(type)
    End Sub
 
    Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
      Return sourceType Is GetType(String) OrElse TypeDescriptor.GetConverter(GetType([Enum])).CanConvertFrom(context, sourceType)
    End Function
 
    Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
      If TypeOf value Is String Then
        Return GetEnumValue(EnumType, DirectCast(value, String))
      End If
      If TypeOf value Is [Enum] Then
        Return GetEnumDescription(DirectCast(value, [Enum]))
      End If
      Return MyBase.ConvertFrom(context, culture, value)
    End Function
 
    Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
      Return If(TypeOf value Is [Enum] AndAlso destinationType Is GetType(String), GetEnumDescription(DirectCast(value, [Enum])), (If(TypeOf value Is String AndAlso destinationType Is GetType(String), GetEnumDescription(EnumType, DirectCast(value, String)), MyBase.ConvertTo(context, culture, value, destinationType))))
    End Function
 
    Public Shared Function GetEnumDescription(value As [Enum]) As String
      Dim fieldInfo = value.[GetType]().GetField(value.ToString())
      Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
      Return If((attributes.Length > 0), attributes(0).Description, value.ToString())
    End Function
 
    Public Shared Function GetEnumDescription(value As Type, name As String) As String
      Dim fieldInfo = value.GetField(name)
      Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
      Return If((attributes.Length > 0), attributes(0).Description, name)
    End Function
 
    Public Shared Function GetEnumValue(value As Type, description As String) As Object
      Dim fields = value.GetFields()
      For Each fieldInfo As FieldInfo In fields
        Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
        If attributes.Length > 0 AndAlso attributes(0).Description = description Then
          Return fieldInfo.GetValue(fieldInfo.Name)
        End If
        If fieldInfo.Name = description Then
          Return fieldInfo.GetValue(fieldInfo.Name)
        End If
      Next
      Return description
    End Function
  End Class
End Namespace

Usage example

EnumDescriptionTypeConverter class is used here as default type converter

using System;
using System.ComponentModel;
using Karmian.Core.TypeConverters;
 
namespace GoldenSharp.Common
{
  [TypeConverter(typeof(EnumDescriptionTypeConverter))]
  public enum TargetFramework
  {
    [Description("Default")]
    Default,
    [Description("ISO-1")]
    ISO_1,
    [Description("ISO-2")]
    ISO_2,
    [Description("C# 3.0")]
    CS_3
  }
}

Imports System.ComponentModel
Imports Karmian.Core.TypeConverters
 
Namespace GoldenSharp.Common
	<TypeConverter(GetType(EnumDescriptionTypeConverter))> _
	Public Enum TargetFramework
		<Description("Default")> _
		[Default]
		<Description("ISO-1")> _
		ISO_1
		<Description("ISO-2")> _
		ISO_2
		<Description("C# 3.0")> _
		CS_3
	End Enum
End Namespace

Comments

not working

I use mvc 4

Can you please paste error

Can you please paste error you get?

Corrected! Thanks for your

Corrected! Thanks for your submission!

Small VB.Net Err

Canned VB to C# converters routinely mess a few things up. In the GetEnumValue function, this line:

foreach (var fieldInfo in fields)

is incorrectly converted to

For Each fieldInfo As var In fields
Well, var is not a proper type....

'fields' is an array of objects so this will work:
For Each fieldInfo As Object In fields

But I suspect the best way is:
For Each fieldInfo As System.Reflection.FieldInfo In fields
or
For Each fieldInfo As FieldInfo In fields
if System.Reflection is imported

Both seem to work

HTH and THANKS!

Post new comment

  • Lines and paragraphs are automatically recognized. The <br /> line break, <p> paragraph and </p> close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
1 + 1 =
This simple math problem is designed for BOT - you just have to enter '7'.