私はLEDを表すクラスを書いています。 255タイプがこの一般的なクランプ方法のために推論されないのはなぜですか?
から0の範囲内のR、G、Bのための基本的3 uint
値私はC#に新たなんだと私がしたいことを8ビットよりも大きいのuint 、始まりました。自分のクランプメソッドを書く前に、私はオンラインで1つを探して、this great looking answerが拡張メソッドを提案していることを発見しました。問題は、タイプがuint
であると推論できないことです。どうしてこれなの?このコードにはすべてが書かれています。私はそれを動作させるために型を明示的に与える必要があります。 byte
を使用して
class Led
{
private uint _r = 0, _g = 0, _b = 0;
public uint R
{
get
{
return _r;
}
set
{
_r = value.Clamp(0, 255); // nope
_r = value.Clamp<uint>(0, 255); // works
}
}
}
// https://stackoverflow.com/a/2683487
static class Clamp
{
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
else if (val.CompareTo(max) > 0) return max;
else return val;
}
}
間違い
は、当然のことながら移動するための方法です。しかし私はまだ質問に対する答えに興味があります。
ちょうどメモとして、私はこのジェネリックをもう少し制限しようとします。 'IComparable'を実装するすべての型が 'Clamp'関数を得る方法は、意味的には正しくない可能性があります。これは、Tがisa(byte、sbyte、int、uint)のような特定の型に 'T 'を制限することができないという状況の1つです。 –
@RonBeyer Eric Lippertによると、' IComparable 'インターフェースは総注文を提供する必要があります。それで、なぜ「クランプ」は、たとえ文字列上であっても、意味的に正しいわけではないのですか? –
Rawling
@Rawling例えば、 'string'は' IComparable 'を実装しています。これは' Clamp'(意味はありますが、文字列ではありません)に対して意味的に正しいものではありません。 –