-3

リストに新しい項目を追加する関数に一般的なリストを渡そうとしています。私は次のような単純化された例を持っています:

   private void SetBayNumb<T>(ObservedList<T> bayList) where T : IBaySpec, new()
   {
     var bay = new T();
     bayList.Add(bay);
   }

それを呼び出すメソッドに次のエラーがあります。

T' must have a public parameterless constructor in order to use it as parameterジェネリック型またはメソッドの型T'

私がやろうとしていることは可能ですか?コンパイラは、それがどのようなリストであるかを気にするべきではないので、それはそうあるべきだと思います.パブリックのパラメータなしのコンストラクタを呼び出して、渡された既存のリストに新しいインスタンスを追加するだけです.

問題は、インターフェイスが実装者にパブリックコンストラクターがあることを保証していないことだと思いましたが、具体的なクラスを指定しても、次のエラーが発生します。

T' must be convertible toジェネリック型またはメソッドでパラメータ `T' として使用するためのタイプBayClass'

任意のポインタに非常に感謝します。

4

2 に答える 2

5

苦情はリストに関するものではなく、 に関するものTです。ObservedList<MyClass>があり、それを に渡す場合はSetBayNumb()MyClass実装IBaySpecする必要があり、パラメーターなしのコンストラクターが必要ですpublic MyClass() { ... }。なんで?そう言っているからwhere T : IBaySpec, new()です。節を削除するwhereと、エラーはなくなりますが、発言できなくなりますnew T()

于 2015-02-05T22:02:18.750 に答える
3

あなたの呼び出しコードは次のように見えると思います

 void Method<T>(ObservedList<T> bayList)
 {
    SetBayNumb<T>(bayList);
 }

問題は、Tin に制限がないMethodため、コンパイラが の引数と一致しないという事実から生じますSetBayNumb

ジェネリック型名は単なる名前であることに注意してください。好きな名前を選ぶことができ、エラーについての推論に役立ちます。次のように、異なる名前のジェネリック引数を使用して同じメソッドを書き換えます。

 void Method<TArg>(ObservedList<TArg> bayList)
 {
    SetBayNumb<TArg>(bayList);
 }

より良いエラーが発生します:

型 'TArg' には、ジェネリック型またはメソッドでパラメーター 'T' として使用するために、パラメーターなしのパブリック コンストラクターが必要です。

このエラーには 2 つの異なるタイプが関係していることに注意してください (両方が同じ "T" と呼ばれるとわかりにくい)。

修正:

  • 外側のジェネリック メソッドに同じ制限を指定する ( Method<TArg>(ObservedList<TArg> bayList) where TArg : ... new())
  • T個々のメソッドではなくジェネリック クラス レベルで指定する
  • 両方の要件を満たす具体的なクラスを渡します (リスト内の項目のクラスは、インターフェイスを実装し、パラメーターのないコンストラクターを持つ必要があります)。
于 2015-02-05T22:40:09.813 に答える