2014-02-18 65 views
0

我想创建一个扩展方法,将任何枚举转换为Json字符串。我可以扩展Enum a la Enum.GetValues()吗?

我想能够附加一个扩展方法给枚举,我可以通过枚举类型,以便它可以调用Enum调用Enum.GetValues(Type enumType),所以它可能看起来像:

Enum.ToJsonString(Type enumType) 

看来,这是不可能的 - 枚举是一个抽象类;你怎么能延长这一点? - 而且我将不得不创建自己的静态类型来实现这一点。

任何人都可以证实我不能扩展Enum这种方式(请解释,技术上,为什么),或告诉我怎么可以?

澄清(更新)

我知道我可以用我自己的静态类型做到这一点。例如,创建EnumExtensions.ToJsonString(Type enumType)相当容易,但我宁愿将方法与GetValues()等一起列出,并使用VS intellisence自动完成。

+1

你的意思是任何枚举或任何枚举*值*?扩展方法总是显示为* instance *方法,而不是静态方法。了解更多关于你希望你的方法做什么以及如何调用它的信息会很有用。 –

+0

我的意思是任何枚举。我希望能够将任何枚举的所有可能值转换为带有名称/散列码作为json中的键/值对象的json字符串。 – Faust

回答

5

如C#定义extension methods

扩展方法使你的方法“添加”到现有各类 而无需创建一个新的派生型,重新编译,或以其他方式 修改原始类型。扩展方法是一种特殊的 静态方法,但它们被称为实例方法 的扩展类型。

应该调用它们,因为它们是实例类型的方法。 Enum是一个类型名称,并且您正在尝试编写看起来类似于静态成员的扩展,这不可能是

你可以做的是通用的方法,将接受枚举类型和枚举值转换成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); 
} 

而且随着

var json = GetEnumJson<DayOfWeek>(); 

使用它,或者,如果你有这个方法JsonHelper类然后我会去与名GetEnumMembers和 称呼它:

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

结果:

{ “星期日”:0, “星期一”:1, “星期二”:2, “星期三”:3, “星期四”:4, “星期五”:5, “星期六” :6}

+0

查看OP的更新。 – James

+0

@詹姆斯基本上没有什么改变 - 答案仍然*'不可能'* :) –

+0

看来这可能是最终答案(我会给它一段时间)。我喜欢另一种泛型方法,尽管我很惊讶我不能指定'where T:Enum',如果参数不是枚举,我必须抛出一个异常......这让人感觉很笨拙。 – Faust

1

您可以添加扩展到所有类型和检查中,如果枚举这样

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 */ 
    } 
} 

,并使用它像

enum MyEnum 
{ 
    MyValue1, 
    MyValue2, 
} 

.... 

var json = typeof(MyEnum).ToJsonString(); 
2

这个怎么样,你不能做它作为一个扩展,因为你不能在c#中做静态扩展(在写作时)。

请注意,如果两个枚举成员具有相同的值(这是不寻常,但有效。)

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