C# 中的枚举类型约束
可能的重复:
任何人都知道一个好的解决方法缺少枚举通用约束?
C# 不允许对 Enum
进行类型约束的原因是什么?我确信疯狂背后有一种方法,但我想了解为什么这是不可能的。
以下是我希望能够做到的(理论上)。
public static T GetEnum<T>(this string description) where T : Enum
{
...
}
Possible Duplicate:
Anyone know a good workaround for the lack of an enum generic constraint?
What is the reason behind C# not allowing type constraints on Enum
's? I'm sure there is a method behind the madness, but I'd like to understand why it's not possible.
Below is what I would like to be able to do (in theory).
public static T GetEnum<T>(this string description) where T : Enum
{
...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
事实上,这是可能的,只是用了一个丑陋的把戏。
但是,它不能用于扩展方法。
如果需要,您可以为
Enums
提供一个私有构造函数和一个公共嵌套抽象继承类,其中Temp
作为Enum
,以防止非枚举的继承版本。请注意,您不能使用此技巧来创建扩展方法。
Actually, it is possible, with an ugly trick.
However, it cannot be used for extension methods.
If you want to, you can give
Enums<Temp>
a private constructor and a public nested abstract inherited class withTemp
asEnum
, to prevent inherited versions for non-enums.Note that you can't use this trick to make extension methods.
这是偶尔需要的功能。
正如我喜欢指出的那样,在有人设计、规范、实现、测试、记录和发布该功能之前,所有功能都不会实现。到目前为止,还没有人为此做到这一点。没有什么特别不寻常的理由可以解释为什么不这样做。我们还有很多其他事情要做,但预算有限,而这件事从来没有超越“这不是很好吗?”的问题。语言设计团队的讨论。
CLR 不支持它,因此为了使其工作,除了语言工作之外,我们还需要执行运行时工作。(参见答案评论)我可以看到有一些不错的使用案例,但没有一个如此引人注目,以至于我们会做这项工作,而不是数百个其他更频繁请求的功能之一,或者有更引人注目和影响更深远的使用案例。 (如果我们要修改这段代码,我个人会优先考虑委托约束方式,远高于枚举约束。)
This is an occasionally requested feature.
As I'm fond of pointing out, ALL features are unimplemented until someone designs, specs, implements, tests, documents and ships the feature. So far, no one has done that for this one. There's no particularly unusual reason why not; we have lots of other things to do, limited budgets, and this one has never made it past the "wouldn't this be nice?" discussion in the language design team.
The CLR doesn't support it, so in order to make it work we'd need to do runtime work in addition to the language work.(see answer comments)I can see that there are a few decent usage cases, but none of them are so compelling that we'd do this work rather than one of the hundreds of other features that are much more frequently requested, or have more compelling and farther-reaching usage cases. (If we're going to muck with this code, I'd personally prioritize delegate constraints way, way above enum constraints.)
它回答了你的问题吗?
Does it answer your question?
IL Weaving 使用 ExtraConstraints
你的代码
编译了什么
IL Weaving using ExtraConstraints
Your Code
What gets compiled
这是 SLaks 出色的丑陋技巧的 VB.NET 版本,其中
Imports
作为“typedef” :(类型推断按预期工作,但无法获取扩展方法。)
输出:
Here's a VB.NET version of SLaks excellent ugly trick, with
Imports
as a "typedef":(Type inference works as expected, but you can't get extension methods.)
Output:
这里的一件奇怪的事情是,您可能想要编写大量通用 Enum 方法,其实现取决于枚举的“基本”类型。
枚举的“基本”类型
E
是指System
命名空间中的类型,其名称与System 成员的名称相同通过调用
用于类型System 获取的 .TypeCode
枚举.Type.GetTypeCode(System.Type)E
。如果枚举是在 C# 中声明的,则这与声明为“继承”的类型相同(我不确定规范中的正式名称)。例如,下面的Animal
枚举的基类型是System.Byte
:可以使用 switch 语句编写这样的方法,但它确实很难看,你不能获取强类型参数或返回其类型是枚举的基类型的类型,并且您必须重复元数据查找或进行一些缓存(例如,在包含该方法的泛型类型的静态构造函数中)。
One quirky thing here is that there are a fair number of generic Enum methods you might want to write whose implementation depends on the "base" type of the enumeration.
By the "base" type of an enumeration,
E
, I mean the type in theSystem
namespace whose name is the same as the name of the member ofSystem.TypeCode
enumeration obtained by callingSystem.Type.GetTypeCode(System.Type)
for the typeE
. If the enumeration was declared in C#, this is the same type that it was declared to "inherit" from (I'm not sure what this is officially called in the spec). For example, the base type of theAnimal
enumeration below isSystem.Byte
:It's possible to write such methods using switch statements, but it sure is ugly, you can't get strongly typed parameters or return types whose type is the base type of the enumeration, and you have to either repeat the metadata lookup or do some caching (e.g. in the static constructor for the generic type containing the method).