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约束的两种类型都可以转换为十进制。
BTW,可以在答案中找到可接受的替代编码: How should one best recode this example extension method to be generic for all numeric types?答案 0 :(得分:1)
你不需要泛型。虽然“DRY”的概念使得编写可以适用于所有类型的单个函数的想法,但这种情况下,您最好为每种数字类型设置谨慎的函数。所有数字类型都是已知的,列表不是太大;无论如何,有可能是你实际上不会使用的数字类型。如果你真的(无论出于何种原因)想要一个函数,那么你唯一真正的选择就是你链接到的IComparable
选项,这会导致对数字参数造成限制的不幸(和不必要的)后果。
话虽如此,您的问题是您不能拥有T : decimal, double
,因为这意味着T
必须 decimal
和double
(这是不可能的),而不是它可以是一个。
此外,由于这就是这个函数所做的一切,我可能无论如何都不会调用Math.Max
和Math.Min
函数。用这样的方式编写函数可能就是这么简单,如果不是稍微清楚一点:
public static decimal ClipGN(this decimal v, decimal lo, decimal hi)
{
return v <= lo ? lo : v >= hi ? hi : v;
}
您应该能够逐字复制此代码(当然,除了返回和参数类型之外)。
答案 1 :(得分:1)
我自己尝试编译代码并且自己收到以下错误:
'double'不是有效的约束。用作约束的类型必须 是一个接口,一个非密封类或一个类型参数。 (CS0701)
decimal
相同。这表明,decimal
和double
都不允许约束类型参数T,因为可以满足该约束的唯一类型本身(它与制作非泛型重载没有区别,取而代之的是T使用decimal
或double
)。即使单独允许它们约束T(它们不是),仍然不允许组合约束,因为任何类型都不能同时为decimal
和double
。
如果约束条件为where T : IComparable<T>
,则不同,其中两种类型以及其他类型都可以满足该约束条件。