我可以将 Enum 扩展为 Enum.GetValues() 吗? [复制]
Posted
技术标签:
【中文标题】我可以将 Enum 扩展为 Enum.GetValues() 吗? [复制]【英文标题】:Can I extend Enum a la Enum.GetValues()? [duplicate] 【发布时间】:2014-03-18 04:43:54 【问题描述】:我想创建一个将任何枚举转换为 Json 字符串的扩展方法。
我希望能够将扩展方法附加到 Enum 中,我可以将枚举类型传递到其中,以便可以在 Enum
上调用它,就像你可以调用 Enum.GetValues(Type enumType)
一样,所以它可能看起来像:
Enum.ToJsonString(Type enumType)
这似乎是不可能的——Enum是一个抽象类;你怎么能延长它? -- 而且我必须创建自己的静态类型来实现它。
谁能确认我不能以这种方式扩展 Enum(请从技术上解释为什么),或者告诉我该怎么做?
澄清(更新)
我知道我可以用我自己的静态类型来做到这一点。例如,创建EnumExtensions.ToJsonString(Type enumType)
相当容易,但我宁愿将方法与 GetValues() 等一起列出,并使用 VS 智能自动完成。
【问题讨论】:
你是指任何枚举,还是任何枚举值?扩展方法总是看起来好像它们是 instance 方法,而不是静态方法。了解更多关于您希望您的方法做什么以及如何调用它会很有用。 我的意思是任何枚举。我希望能够将任何枚举的所有可能值转换为 json 字符串,其中名称/哈希码作为 json 中的键/值对象。 【参考方案1】:正如extension methods在C#中定义的那样:
扩展方法使您能够将方法“添加”到现有类型 无需创建新的派生类型、重新编译或以其他方式 修改原始类型。扩展方法是一种特殊的 静态方法,但它们被调用就好像它们是 instance 方法 扩展类型。
它们应该被调用,因为它们是类型的实例方法。 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
【讨论】:
@James 基本上没有任何改变 - 答案仍然是 '不可能' :) 看来这可能是最终的答案(我会给出一段时间)。我喜欢另一种通用方法,但我很沮丧我不能指定where T: Enum
,如果参数不是枚举,我必须抛出异常......这让人感觉很笨拙。
不错的代码@SergeyBerezovskiy! :)
@Faust 同意你的观点——泛型类型参数约束在 C# 中不是很灵活——你不能添加枚举约束。但我至少会为值类型添加约束。另请参阅 ken2k 提到的问题
@Jodrell 你是神话终结者 :)【参考方案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);
【讨论】:
【参考方案3】:您可以为所有类型添加扩展,并在内部检查它是否像这样枚举
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();
【讨论】:
以上是关于我可以将 Enum 扩展为 Enum.GetValues() 吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章