是否可以在c#中定义枚举的隐式转换?
可以实现这一目标的东西?
public enum MyEnum
{
one = 1, two = 2
}
MyEnum number = MyEnum.one;
long i = number;
如果没有,为什么不呢?
有关这方面的进一步讨论和想法,我跟进了我目前处理这个问题的方法:Improving the C# enum
是否可以在c#中定义枚举的隐式转换?
可以实现这一目标的东西?
public enum MyEnum
{
one = 1, two = 2
}
MyEnum number = MyEnum.one;
long i = number;
如果没有,为什么不呢?
有关这方面的进一步讨论和想法,我跟进了我目前处理这个问题的方法:Improving the C# enum
11 回答
如果将枚举的基数定义为long,则可以执行显式转换 . 我不知道你是否可以使用隐式转换,因为枚举不能在它们上定义方法 .
此外,请注意,未经初始化的枚举将默认为0值或第一项 - 因此在上述情况下,最好定义
zero = 0
.你可能可以,但不是枚举(你不能添加一个方法) . 您可以向自己的类添加隐式转换,以允许将枚举转换为它,
问题是为什么?
通常.Net避免(并且你也应该)任何可能丢失数据的隐式转换 .
您不能在枚举类型上声明隐式转换,因为它们无法定义方法 . C#implicit关键字编译成一个以'op_'开头的方法,在这种情况下它不起作用 .
我在MS .net(非Mono)上运行代码时遇到了sehe's answer的问题 . 对我来说,问题特别发生在.net 4.5.1上,但其他版本似乎也受到了影响 .
这个问题
通过反射访问
public static TDervied MyEnumValue
(通过FieldInfo.GetValue(null)
不初始化所述字段 .解决方法
而不是在
RichEnum<TValue, TDerived>
的静态初始化器上为TDerived
实例分配名称,而是在第一次访问TDerived.Name
时懒得完成 . 代码:在我的情况下 - 基于
EquatableBase<T>
:注意
上面的代码没有包含Mark原始答案的所有功能!
谢谢
感谢Mark提供了他的
RichEnum
实施,并感谢sehe提供了一些改进!我改编了Mark优秀的RichEnum通用基类 .
定影
由于缺少来自其库的位而导致的许多编译问题(特别是:资源相关的显示名称未被完全删除;它们现在是)
初始化没有't perfect: if the first thing you did was access the static .Values property from the base class, you'得到一个NPE . 通过强制基类强制递归(CRTP)在CheckInitialized期间及时强制TDerived的静态构造来解决此问题
最后将CheckInitialized逻辑移动到一个静态构造函数中(为了避免每次检查的惩罚,多线程初始化时的竞争条件;也许这是我的子弹1解决的不可能性 . ?)
感谢Mark为这个出色的想法实施,大家向大家致意:
我在单声道上运行的一个使用示例:
产生输出
注意:mono 2.6.7需要使用单声道2.8.2时不需要的额外显式强制转换...
有一个解决方案 . 考虑以下:
以上提供隐式转换:
这比声明一个普通的枚举更加重要(尽管你可以将上面的一些重构为一个通用的通用基类) . 您可以通过让基类实现IComparable和IEquatable,以及添加方法来返回DescriptionAttributes的值,声明的名称等等,甚至可以更进一步 .
我编写了一个基类(RichEnum <>)来处理大部分繁琐的工作,这使得上面的枚举声明简化为:
基类(RichEnum)如下所示 .
你不能做隐含的转换(零除外),你不能编写自己的实例方法 - 但是,你可以编写自己的扩展方法:
但是,这并没有给你很多(与仅进行显式演员相比) .
我见过人们想要的主要时间之一是通过泛型进行
[Flags]
操作 - 即bool IsFlagSet<T>(T value, T flag);
方法 . 不幸的是,C#3.0不支持泛型运算符,但是你可以使用things like this来解决这个问题,这使得运算符完全可用于泛型 .我从这里找到了更简单的解决方案https://codereview.stackexchange.com/questions/7566/enum-vs-int-wrapper-struct我从该链接粘贴了下面的代码,以防万一它以后不起作用 .
对我来说,枚举对我来说基本没用,OP .
我最终总是和pic有关:
the simple solution
经典示例问题是用于检测按键的VirtualKey集 .
这里的问题是你不能用枚举索引数组,因为它不能隐式地将枚举转换为ushort(即使我们甚至在ushort上使用enum)
在此特定上下文中,枚举由以下数据结构废弃 . . . .
引入枚举类型的隐式转换会破坏类型安全性,所以我不建议这样做 . 你为什么想这么做?我见过的唯一用例是当你想将枚举值放入具有预定义布局的结构中时 . 但即使这样,你也可以在结构中使用枚举类型,然后告诉Marshaller他应该怎么做 .