C#3.0中的“特殊类”枚举是否存在通用类型约束的解决方法?
参见英文答案 >
Anyone know a good workaround for the lack of an enum generic constraint?10个
你好, 请考虑以下扩展方法: public static bool HasFlags<T>(this T value,T flags) where T : System.Enum { // ... } 您可能会知道,这将在编译时抛出错误,因为类通常不允许继承自System.Enum.问题是使用枚举关键字指定的任何枚举实际上都是继承自System.Enum,因此上述代码将是将扩展方法限制为枚举的理想方式. 现在这里明显的工作是使用枚举而不是T,但是你失去了通用类型的好处: MyEnum e; e.HasFlags(MyOtherEnum.DoFunkyStuff); 上面的代码将使用泛型类型抛出编译时错误,而它只能使用枚举类型(如果我实现它)来引发运行时错误.) 有没有任何编译器选项可以用来关闭约束检查,还是有其他一些漂亮的方法呢? 在建议之前,我想说,我不会使用T:struct或其他一些,因为你可以做一些奇怪的东西,如123.HasFlags(456). 我很遗憾为什么这个错误存在于所有…这是同样的问题,你会得到使用在哪里T:System.Object,但是,你有哪里T:类…为什么没有在哪里T:枚举?
解决方法
编辑:现在可以通过ildasm / ilasm:
UnconstrainedMelody来支持这个库.
C#团队的成员之前曾表示过希望能够支持T:Enum和T:T代表的地位,但这并不是一个很高的优先级. (我不知道有什么理由是有限制在第一位,诚然…) C#中最实用的解决方法是: public static bool HasFlags<T>(this T value,T flags) where T : struct { if (!(value is Enum)) { throw new ArgumentException(); } // ... } 这会丢失对“枚举”的编译时检查,但是在两个地方都要保持检查是否使用相同的类型.当然,它还有执行时间的罚款.在第一次调用之后,您可以通过使用通用嵌套类型在静态构造函数中抛出异常的实现来避免执行时间的惩罚: public static bool HasFlags<T>(this T value,T flags) where T : struct { if (!(value is Enum)) { throw new ArgumentException(); } return EnumHelper<T>.HasFlags(value,flags); } private class EnumHelper<T> where T : struct { static EnumHelper() { if (!typeof(Enum).IsAssignableFrom(typeof(T)) { throw new InvalidOperationException(); // Or something similar } } internal static HasFlags(T value,T flags) { ... } } 正如Greco所说,您可以在C/C++LI中编写该方法,然后从C#引用类库作为另一个选项. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |