模拟实现接口的枚举的行为
假设我有一个类似的枚举:
enum OrderStatus
{
AwaitingAuthorization,
InProduction,
AwaitingDespatch
}
我还在枚举上创建了一个扩展方法来整理 UI 中显示的值,所以我有类似的东西:
public static string ToDisplayString(this OrderStatus status)
{
switch (status)
{
case Status.AwaitingAuthorization:
return "Awaiting Authorization";
case Status.InProduction:
return "Item in Production";
... etc
}
}
受到优秀帖子的启发 此处,我想将我的枚举绑定到 SelectList
具有扩展方法:
public static SelectList ToSelectList
但是,要在 UI 下拉列表中使用 DisplayString 值,我需要添加一个约束沿着
: where TEnum has extension ToDisplayString
显然,这些都不适用于当前的方法,除非有一些我不知道的聪明技巧。
有人对我如何实现这样的事情有任何想法吗?
Say I have an enum something like:
enum OrderStatus
{
AwaitingAuthorization,
InProduction,
AwaitingDespatch
}
I've also created an extension method on my enum to tidy up the displayed values in the UI, so I have something like:
public static string ToDisplayString(this OrderStatus status)
{
switch (status)
{
case Status.AwaitingAuthorization:
return "Awaiting Authorization";
case Status.InProduction:
return "Item in Production";
... etc
}
}
Inspired by the excellent post here, I want to bind my enums to a SelectList
with an extension method:
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
however, to use the DisplayString values in the UI drop down I'd need to add a constraint along the lines of
: where TEnum has extension ToDisplayString
Obviously none of this is going to work at all with the current approach, unless there's some clever trick I don't know about.
Does anyone have any ideas about how I might be able to implement something like this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是否有令人信服的理由在这里使用
enum
?当您开始疯狂地使用枚举时,可能是时候使用类了。
您使用它的方式与
enum
相同:字符串表示形式是内置的,您所需要的只是
ToString()
。Is there a compelling reason to use an
enum
here?When you start jumping through crazy hoops to use
enum
s, it might be time to use a class.You consume it the same as an
enum
:The string representation is built-in, and all you need is
ToString()
.当然,您可以使用
DisplayAttribute
来注释您的Enum
。您还可以选择创建一个扩展方法,该方法采用任何枚举值并根据设置的属性返回其显示名称,以整理 UI 中显示的值,如下所示:
使用
代码:
结果
为了类型安全,我不会使用扩展方法,而是使用处理 Enum 类型的静态类:
C# 7.3 之前的版本。由于
Enum
在 7.3 之前不是有效的类型约束(并且会导致编译时异常),因此您最终会认为枚举是值类型,并且它们实现了一些接口,以便将类型参数限制为尽可能接近Enum
。C# 7.3+ 版本,带有编译时间检查...耶!
类的 GetValues 方法:
如果您遵循枚举指南 并包含默认(零)值,我们可以忽略它(有时我们想显示“未选择”之类的值,有时我们不想显示“无效选择”)。
然后我们可以添加另一个方法:
Of course, you can use the
DisplayAttribute
to annotate yourEnum
s.You can also opt to create an extension method taking any enumeration value and returning its display name based on the attribute set to it to tidy up the displayed values in the UI, as follows:
With
Code:
Results
For type safety, I wouldn't use an extension methods, but instead a static class that deals with the Enum type:
Pre C# 7.3 version. Since
Enum
is not a valid type constraint prior to 7.3 (and it would cause a compile-time exception), you'll end up by considering that enums are value types and they implement some interfaces, in order to restrict the type parameter as close toEnum
as possible.C# 7.3+ version, with compile time checking... yay!
GetValues Method for the class:
If you follow Enum Guidelines and include the Default (zero) value, we can ignore it (sometimes we want to display the value like "None Selected" and sometimes we don't "Invalid Selection").
Then we can add another method:
不要使用“ToDisplayString”,只需覆盖枚举的 ToString() 即可。因此,如果枚举覆盖它,它将采用它,否则它将采用默认的 ToString 行为(在 ToSelectList 中)。
Instead of using "ToDisplayString", simply override ToString() of your enum. So if an enum overrides it it will take it, otherwise it will take the default ToString behavior (in ToSelectList).
如果您只需要使用相对较小的枚举类,这些类仅具有显式转换运算符 ToString,并且对于
System
及其派生命名空间上的枚举的特殊类不需要其他可用性,那么以下内容示例可能是一个解决方案:If you just need to use relatively tiny enumerate classes that have no more than an explicit casting operator, ToString and do not take other usability for the special ones about enum on
System
and its derived namespaces, then the following example could be a solution:您可以这样做:
然后将 TEnum 限制为 Enum:
where TEnum : System.Enum
当然,这样您就可以在 Enum 本身上获得一堆方法并失去类型安全性。
You could do this:
Then restrict TEnum to Enum:
where TEnum : System.Enum
Of course, that way you get a bunch of methods on the Enum itself and lose type safety.