次のようなジェネリック メソッドを定義する基本クラスがあります。
public class BaseClass
{
public T DoSomething<T> ()
{ ... }
}
このクラスはサードパーティ製であり、インターフェイスが付属していないため、そのクラスから実際に必要なメソッドを定義するインターフェイスを定義しています。そうすれば疎結合になり、実際にそのサードパーティ クラスを別のものと交換できます。この例では、次のインターフェイスを検討してください。
public interface ISomething
{
T DoSomething<T> ()
where T : Foo;
}
ご覧のとおり、同じメソッドを定義していますが、型パラメータに型制約も適用しています。これは、これに関係のない他の要件から来ています。
次に、BaseClass
も実装するサブタイプを定義しますISomething
。このクラスは、インターフェースの背後にある通常の実装として使用されますが、インターフェースはアプリケーションの残りの部分がアクセスするものになります。
public class Something : BaseClass, ISomething
{
// ...
}
はすでに任意の型パラメータをサポートDoSomething
しているため、特に のサブタイプである型パラメータをサポートする必要があります。したがって、 のサブタイプがすでにインターフェースを実装していると予想されます。ただし、次のエラーが表示されます。BaseClass
T
Foo
BaseClass
メソッド 'BaseClass.DoSomething()' の型パラメーター 'T' の制約は、インターフェイス メソッド 'ISomething.DoSomething()' の型パラメーター 'T' の制約と一致する必要があります。代わりに、明示的なインターフェイスの実装を使用することを検討してください。
さて、私には 2 つの可能性があります。最初のものは、エラーが示唆することを行い、インターフェースを明示的に実装することです。2 つ目は、次を使用して基本実装を非表示にすることnew
です。
// Explicit implementation
T ISomething.DoSomething<T> ()
{
return base.DoSomething<T>();
}
// Method hiding
public new T DoSomething<T>()
where T : Foo
{
return base.DoSomething<T>();
}
どちらも機能しますが、クラス自体からメソッドにアクセスできるようにするために、おそらく2番目のソリューションを好むでしょう。ただし、次の疑問が残ります。
基本型がより厳密でない (読み取り: なし) 型制約を使用してメソッドを既に実装している場合、なぜメソッドを再実装する必要があるのですか? メソッドをそのまま実装する必要があるのはなぜですか?
編集:メソッドにもう少し意味を持たせるために、戻り値の型を から に変更しvoid
ましたT
。私の実際のアプリケーションでは、ジェネリック引数と戻り値の両方があります。