T
ジェネリックを使用してジェネリック型の引数を次のものだけに制限する方法があるかどうか教えてください。
Int16
Int32
Int64
UInt16
UInt32
UInt64
キーワードは知っていますが、これらの型のみwhere
のインターフェースを見つけることができません。
何かのようなもの:
static bool IntegerFunction<T>(T value) where T : INumeric
ベストアンサー1
10年以上経って、この機能はついに.NET 7最も一般的なインターフェースはINumber<TSelf>
(System.Numerics
名前空間内)であり、すべての数値を網羅しています。整数型のみを受け入れるには、IBinaryInteger<TSelf>
その代わり。
実装例を次に示しますIntegerFunction
。
static bool IntegerFunction<T>(T value) where T : IBinaryInteger<T> {
return value > T.Zero;
}
Console.WriteLine(IntegerFunction(5)); // True
Console.WriteLine(IntegerFunction((sbyte)-5)); // False
Console.WriteLine(IntegerFunction((ulong)5)); // True
以下の(現在は廃止されている)元の回答は、歴史的な観点から残されています。
C#はこれをサポートしていません。Hejlsbergは、この機能を実装しない理由を説明しています。ブルース・エッケルとのインタビューで:
また、複雑さが増すことが、得られるわずかな成果に見合うかどうかは明らかではありません。実行したいことが制約システムで直接サポートされていない場合は、ファクトリ パターンを使用して実行できます。たとえば、 があり
Matrix<T>
、その中でMatrix
ドット積メソッドを定義したいとします。もちろん、それは最終的に 2 つの を乗算する方法を理解する必要があることを意味しますT
が、少なくとも が、、または のT
場合は、それを制約として指定することはできません。ただし、を引数としてとし、 に というメソッドを用意することはできます。それを実装して に渡します。int
double
float
Matrix
Calculator<T>
Calculator<T>
multiply
Matrix
しかし、これはかなり複雑なコードにつながり、ユーザーは使用したいCalculator<T>
ものごとに独自の実装を用意する必要があります。拡張可能である必要がない限り、つまり、や などT
の固定数の型だけをサポートしたい場合は、比較的単純なインターフェースで済みます。int
double
var mat = new Matrix<int>(w, h);
ただし、ユーザーが独自のカスタム型を提供できるようにしたい場合は、この実装を公開して、ユーザーが独自のCalculator
インスタンスを提供できるようにする必要があります。たとえば、カスタムの 10 進浮動小数点実装を使用する行列をインスタンス化するには、DFP
次のコードを記述する必要があります。
var mat = new Matrix<DFP>(DfpCalculator.Instance, w, h);
… のすべてのメンバーを実装しますDfpCalculator : ICalculator<DFP>
。
残念ながら同じ制限がある代替案としては、ポリシークラスを使用することです。Sergey Shandarの回答で議論されているように。