2014-02-18 62 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); 
}