为什么编译器不接受这个通用函数?

发布于 2024-11-30 17:58:28 字数 485 浏览 0 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酒浓于脸红 2024-12-07 17:58:28

我尝试自己编译该代码,但我自己收到以下错误:

“double”不是有效的约束。用作约束的类型必须
可以是接口、非密封类或类型参数。 (CS0701)

十进制 相同。这表明无论是decimal还是double都不允许约束类型参数T,因为唯一可以满足该约束的类型是它们本身(这与制作非- 通用重载,用decimaldouble替换T)。即使允许它们单独约束 T(但事实并非如此),仍然不应允许组合约束,因为没有类型可以同时是 decimaldouble >。

这与约束读取 where T : IComparable 不同,其中两种类型以及其他类型都可以满足该约束。

I tried compiling that code myself and I receive the following error myself:

'double' is not a valid constraint. A type used as a constraint must
be an interface, a non-sealed class or a type parameter. (CS0701)

Same for decimal. This suggests that neither decimal nor double 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 either decimal or double). 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 a decimal and a double.

This is unlike if the constraint had read where T : IComparable<T>, where both types, as well as other types, can meet that constraint.

陌上芳菲 2024-12-07 17:58:28

为此,您不需要泛型。虽然“DRY”的概念提出了编写适用于所有类型的单个函数的想法,但在这种情况下,您最好为每种数字类型使用离散的函数。所有数字类型都是已知的,并且列表不会太大;无论如何,您可能实际上不会使用某些数字类型。如果您确实(无论出于何种原因)想要一个函数,那么您唯一真正的选择是链接到的 IComparable 选项,该选项会产生不幸(且不必要)的结果,即导致数字参数装箱。

话虽这么说,你的问题是你不能有 T :decimal, double,因为这意味着 T 必须两者 十进制double (这是不可能的),并不是说它可以是其中之一。

此外,由于这就是该函数所做的全部工作,因此我可能不会调用 Math.Max 和 Math.Min 函数。以这种方式编写函数可能同样简单(如果不是稍微清晰一点):

public static decimal ClipGN(this decimal v, decimal lo, decimal hi)
{
    return v <= lo ? lo : v >= hi ? hi : v;
}

并且您应该能够为每个数字类型逐字复制此代码(当然,返回和参数类型除外)。

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 that T must be both decimal and double (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 and Math.Min functions anyway. It's probably just as simple, if not slightly clearer, to write the functions this way:

public static decimal ClipGN(this decimal v, decimal lo, decimal hi)
{
    return v <= lo ? lo : v >= hi ? hi : v;
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文