1. ホーム
  2. c#

[解決済み] ジェネリックメソッドを数値型に制限する制約がありますか?

2022-03-22 14:26:14

質問

ジェネリックスを使用して、ジェネリック型の引数を制限する方法があるかどうか、どなたか教えてください。 T だけにしてください。

  • Int16
  • Int32
  • Int64
  • UInt16
  • UInt32
  • UInt64

を意識しています。 where キーワードのインターフェイスが見つかりません。 のみ といった型があります。

みたいな感じ。

static bool IntegerFunction<T>(T value) where T : INumeric 

解決方法は?

C#はサポートしていません。Hejlsbergは、この機能を実装しない理由を次のように説明しています。 ブルース・エッケルとのインタビューにて :

それに、複雑さを増すことが、得られる小さな収穫に見合うかどうかも明らかではありません。やりたいことが制約システムで直接サポートされていない場合は、ファクトリーパターンで実現することができます。例えば Matrix<T> 例えば、その中で Matrix であれば、内積のメソッドを定義したい。もちろん、それは最終的に2つの T の場合は、少なくとも制約としてそれを言うことはできません。 Tint , double または float . しかし、あなたができることは、あなたの Matrix を引数として取る。 Calculator<T> であり、かつ Calculator<T> というメソッドを持っています。 multiply . それを実装し、それを Matrix .

しかし、これではかなり複雑なコードになってしまい、ユーザーは自分自身で 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の回答で説明されているように .