开发者

Why does the compiler not accept this generic function?

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 numeri开发者_StackOverflow中文版c types?


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜