为什么编译器不接受这个通用函数?
public static T clipGN<T>(this T v, T lo, T hi) where T : decimal,double
{ return Math.Max(lo, Math.Min(hi, v)); }
给出第二行:
Argument 1: cannot convert from 'T' to 'decimal'
为什么?我认为满足 T 约束的两种类型都可以转换为十进制。
顺便说一句,可以在此处的答案中找到可接受的替代编码: 应该如何最好的方法是将这个示例扩展方法重新编码为所有数字类型的通用方法?
public static T clipGN<T>(this T v, T lo, T hi) where T : decimal,double
{ return Math.Max(lo, Math.Min(hi, v)); }
gives for the second line:
Argument 1: cannot convert from 'T' to 'decimal'
Why? I thought both types meeting that T constraint can be converted to decimal.
BTW, an acceptable alternative coding can be found in the answer here:
How should one best recode this example extension method to be generic for all numeric types?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我尝试自己编译该代码,但我自己收到以下错误:
十进制
相同。这表明无论是decimal还是double都不允许约束类型参数T,因为唯一可以满足该约束的类型是它们本身(这与制作非- 通用重载,用decimal
或double
替换T)。即使允许它们单独约束 T(但事实并非如此),仍然不应允许组合约束,因为没有类型可以同时是decimal
和double
>。这与约束读取
where T : IComparable
不同,其中两种类型以及其他类型都可以满足该约束。I tried compiling that code myself and I receive the following error myself:
Same for
decimal
. This suggests that neitherdecimal
nordouble
are allowed to constrain the type parameter T since the only types that could meet that constraint are themselves (it would be no different from making a non-generic overload, replacing T with eitherdecimal
ordouble
). Even if, individually, they were allowed to constrain T (which they are not), the combination constraint should still not be allowed since no type can simultaneously be adecimal
and adouble
.This is unlike if the constraint had read
where T : IComparable<T>
, where both types, as well as other types, can meet that constraint.为此,您不需要泛型。虽然“DRY”的概念提出了编写适用于所有类型的单个函数的想法,但在这种情况下,您最好为每种数字类型使用离散的函数。所有数字类型都是已知的,并且列表不会太大;无论如何,您可能实际上不会使用某些数字类型。如果您确实(无论出于何种原因)想要一个函数,那么您唯一真正的选择是链接到的 IComparable 选项,该选项会产生不幸(且不必要)的结果,即导致数字参数装箱。
话虽这么说,你的问题是你不能有
T :decimal, double
,因为这意味着T
必须两者十进制
和double
(这是不可能的),并不是说它可以是其中之一。此外,由于这就是该函数所做的全部工作,因此我可能不会调用 Math.Max 和 Math.Min 函数。以这种方式编写函数可能同样简单(如果不是稍微清晰一点):
并且您应该能够为每个数字类型逐字复制此代码(当然,返回和参数类型除外)。
You don't need generics for this. While the concept of "DRY" makes the idea of coding a single function that can work for all types, this is a case where you're better off having discreet functions for each numeric type. All of the numeric types are known, and the list is not overly large; there are likely numeric types that you aren't actually going to use, anyway. If you really (for whatever reason) want a single function, then your only real option is the
IComparable
option that you linked to, which has the unfortunate (and unnecessary) consequence of causing boxing on the numeric parameters.That being said, your problem is that you cannot have
T : decimal, double
, as that means thatT
must be bothdecimal
anddouble
(which is impossible), not that it can be either one.In addition, since this is all that this function does, I'd probably not call the
Math.Max
andMath.Min
functions anyway. It's probably just as simple, if not slightly clearer, to write the functions this way:And you should be able to duplicate this code verbatim (apart from the return and parameter types, of course) for each of the numeric types.