ジェネリックメソッドを数値型に制限する制約はありますか? 質問する

ジェネリックメソッドを数値型に制限する制約はありますか? 質問する

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場合は、それを制約として指定することはできません。ただし、を引数としてとし、 に というメソッドを用意することはできます。それを実装して に渡します。intdoublefloatMatrixCalculator<T>Calculator<T>multiplyMatrix

しかし、これはかなり複雑なコードにつながり、ユーザーは使用したいCalculator<T>ものごとに独自の実装を用意する必要があります。拡張可能である必要がない限り、つまり、や などTの固定数の型だけをサポートしたい場合は、比較的単純なインターフェースで済みます。intdouble

var mat = new Matrix<int>(w, h);

GitHub Gist での最小限の実装。

ただし、ユーザーが独自のカスタム型を提供できるようにしたい場合は、この実装を公開して、ユーザーが独自のCalculatorインスタンスを提供できるようにする必要があります。たとえば、カスタムの 10 進浮動小数点実装を使用する行列をインスタンス化するには、DFP次のコードを記述する必要があります。

var mat = new Matrix<DFP>(DfpCalculator.Instance, w, h);

… のすべてのメンバーを実装しますDfpCalculator : ICalculator<DFP>

残念ながら同じ制限がある代替案としては、ポリシークラスを使用することです。Sergey Shandarの回答で議論されているように

おすすめ記事