2011-07-01 1 views
7

一つは、(例えば、タイプTはパラメータを取らず、int型を返す関数xを持っている必要があります)あなたは(暗黙的に)特定の種類の署名を必要とすることができるということです。 C#のジェネリックは何か類似していますか?C#ジェネリックスは型シグネチャの制約をサポートしていますか? C++テンプレートと利点の

私は基本クラスまたはインターフェイスに基づく制約を認識していますが、これは私が探しているものではありません。

(C++プログラマの学習C#などの私は、これはあなたがC#で望む機能であると誤解される可能性があります。この上の任意のコメントが同様にappriciatedされるだろう...)

+4

しかし、インタフェースの制約は、 'Tがシグネチャと一致するメソッドX()を実装しています 'のようなものを表現するのにかなり良い方法です。 –

答えて

6

あなたがすでに見てきた制約を除いては何もありません(これは公平なものであり、多くの一般的なシナリオをカバーしています)。いくつかの一般的な回避策があります。

  • dynamic、反射またはIL生成など

のいずれかを使用して4.0

  • マニュアルダックタイピングでは、これらのどれもが、静的型チェックなど、しかしを持っていません。

  • +0

    ダイナミックはおそらく私が得ることができる最も近いです。実際には、私はしばしばC++のテンプレートを「動的コンパイル時の言語」と考えています(これはおそらく私以外の誰にも意味をなさないフレーズです:)。 –

    +0

    @Tobias「静的にチェックされたduck-あなたが意味するものは –

    +0

    と突然それは皆に意味がある:) –

    0

    制約の5種類があります。

    1. 派生制約は、タイプパラメータの優越性を示します。
    2. インターフェイス制約は、typeパラメータによって実装されるインターフェイスです。
    3. 値型制約は、型パラメータを値型に制限します。
    4. 参照型制約は、型パラメータを参照型に制限します。
    5. コンストラクタの制約では、typeパラメータにデフォルトコンストラクタまたはパラメータなしコンストラクタがあることが規定されています。

    Thisページが表示されます。

    +0

    "基本クラスまたはインタフェースに基づく制約があることは認識していますが、これは私が探しているものではありません。" –

    4

    はい、インタフェースを介し。特定のインターフェイスを実装する必要があるタイプの汎用オブジェクトを定義できます。そのインターフェース内では、本質的に、そのジェネリックに追加された任意のオブジェクト(例えば、特定の署名を持つリスト)を強制することになります。

    それがあなたのものであるかどうかは、ではなく、が探している通りです。 :)

    +1

    それでも、すべてのオプションをカバーしていない - パラメータ、演算子、静的メソッドを持つコンストラクタなど... –

    +0

    @Marcこの状況では完璧な解決策はありません。 OPは彼の仕事を達成するために少し曲げなければならないだろう。そして、彼はあなたが言及したことのいずれかを必要としないかもしれません。彼はジェネリッククラスが「パラメータを取らずにintを返す関数x」に適合したいと思っています。 –

    +0

    @Marc、私は同意し、非デフォルトコンストラクタのサポート制約は素晴らしいIMHOになります。他の人たち、それほど多くない*特に*演算子:) –

    1

    いいえこれはinterfaceが対象です。タイプ制約に適用するコントラクトを定義したinterfaceを作成します。次に、制約で指定します。

    0

    いいえ、C#ではサポートされていません。あなたが言ったように、最も近いことは、クラスに共通のインタフェースを実装させることです。

    あなた署名による方法を探すことにより、反射で動作を模倣しようとすることができ、それは、実行時制約はなく、コンパイル時の制約です。

    0

    いいえ、C#にはそのような制約はありません。

    ご存知のように、一般的な制約は、基本クラスまたはインタフェースの継承、またはいくつかの他の制約(コンストラクタ制約new()、参照型制約class、値の型制約struct)を強制することができます。

    代理人を使用して、目的の動作を達成することができ、多くの汎用代理人が利用可能な場合があります。
    たとえば、Func<int>は、パラメータを取らずにintを返すデリゲートです。 Func<string, DateTime, int>stringDateTimeを返し、intなどを返します。

    3

    いいえ、これはできません。これは、主にC++テンプレートとC#のジェネリックの違いによって発生します。

    C++テンプレートをコンパイルすると、結果コードのタイプはvector<int>vector<string>のようになります。これはコンパイラが可能なすべての型パラメータを知っていなければならないことを意味しますが、それが正しいかどうかチェックすることもできます。

    C#ジェネリック型をコンパイルすると、実際には1つのジェネリック型、つまりList<T>が作成されます。このため、C#コンパイラはコンパイルタイプで可能なタイプをすべて知っている必要はありません。つまり、バイナリライブラリに汎用タイプを持つことができます。これはC++では不可能です。しかし、これはまた、すべてのタイプをチェックすることができないことを意味します。そのようなことをするためには制約がありますが、C++のコンパイル時間チェックは、ある種のメソッド(インタフェースや基本クラスを使用せずに)や適切な演算子の存在の有無をチェックするようなことはできません。

    C#4で、dynamicを使用して、テンプレートのこの種に幾分同様の効果を得ることができますが、これはあなたが安全性を失うことを意味コンパイル時のチェック、しません - あなたが持っていないタイプで置くことができますが適切なメンバであり、実行時にそのコード行に到達するまではわかりません。

    関連する問題