0

I want to create an extension method that converts any enum into a Json string.

I'd like to be able to attach an extension method to Enum that I can pass an enum-type into, so that it can be called on Enum in the way that you can call Enum.GetValues(Type enumType), so it might look like:

Enum.ToJsonString(Type enumType)

It seems that this is not possible -- Enum is an abstract class; how could you extend that? -- and that I'll have to create my own static type to implement this.

Can anyone either confirm that I cannot extend Enum this way (and please explain, technically, why), or tell me how I can?

Clarification (update)

I know I can do this with my own static type. For example, it would be fairly easy to create EnumExtensions.ToJsonString(Type enumType) but I'd rather have the method listed alongside GetValues() et al with VS intellisence auto-complete.

Faust
  • 15,130
  • 9
  • 54
  • 111
  • 1
    Do you mean any enum, or any enum *value*? Extension methods always appear as if they were *instance* methods, not static methods. It would be useful to see more about what you'd want your method to do, and how it would be called. – Jon Skeet Feb 18 '14 at 12:22
  • I mean any enum. I want to be able to convert all the possible values of any enum into a json string with name/hash-code as key/value objects within the json. – Faust Feb 18 '14 at 12:25

3 Answers3

5

As extension methods defined in C#:

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.

They should be called as they are instance method of type. Enum is a type name, and you are trying to write extension which will look like static member of type, which is not possible.

What you can do is generic method, which will accept type of enum and convert enum values to JSON:

public static string GetEnumJson<T>()
    where T : struct
{
    Type type = typeof(T);
    if (!type.IsEnum)
        throw new NotSupportedException();

    var members = Enum.GetNames(type)
                      .ToDictionary(s => s, s => Enum.Parse(type, s));

    return JsonConvert.SerializeObject(members);
}

And use it with

var json = GetEnumJson<DayOfWeek>();

Or if you have this method in class JsonHelper then I would go with name GetEnumMembers and call it this way:

var json = JsonHelper.GetEnumMembers<DayOfWeek>();

Result:

{"Sunday":0,"Monday":1,"Tuesday":2,"Wednesday":3,"Thursday":4,"Friday":5,"Saturday":6}

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
2

how about this, You can not do it as an extension because you can't do static extensions in c# (at time of writing.)

Note, this code works if two enum members have the same value (which is unusual but valid.)

public static string ToJson<TEnum>()
{
    var enumType = typeof(TEnum);
    if (!enumType.IsEnum)
    {
        throw new ArgumentException("enumType");
    }

    var names = Enum.GetNames(enumType);
    var values = Enum.GetValues(enumType).OfType<Enum>()
        .Select(e => Convert.ChangeType(e, e.GetTypeCode()));
    var members = names.Zip(values, (k, v) => new { k, v })
        .ToDictionary(p => p.k, p => p.v);

    return JsonConvert.SerializeObject(members);
}
Jodrell
  • 34,946
  • 5
  • 87
  • 124
1

You can add extension to all types and inside check if it enum like this

static class EnumEx
{
    public static string ToJsonString(this Type enumType)
    {
        if(!enumType.IsEnum)
            throw new ArgumentException("Type should be enum");

        return /* create json string from enum type */
    }
}

and use it like

enum MyEnum
{
    MyValue1,
    MyValue2,
}

....

var json = typeof(MyEnum).ToJsonString();
Grundy
  • 13,356
  • 3
  • 35
  • 55