web-dev-qa-db-ja.com

C#ジェネリックに特定の基本型を指定できますか?

ジェネリックインターフェイスのタイプが特定の親クラスに基づくことは可能ですか?

例えば:

public interface IGenericFace<T : BaseClass>
{
}

明らかに上記のコードは機能しませんが、機能する場合、コンパイラーに伝えようとしていることは、TBaseClassのサブクラスでなければならないということです。それはできますか、計画はありますか?

特定のプロジェクトの観点からは有用だと思います。コンパイル時に、意図しない型でジェネリックインターフェイス/クラスが使用されないようにします。または、自己文書化するためにも、どのようなタイプが意図されているかを示します。

40
public interface IGenericFace<T> where T : SomeBaseClass
87
Ryan Lundy

あなたが言及しているものは、「一般的な制約」と呼ばれています。ジェネリック型に適用できる制約は数多くあります。

基本的な例は次のとおりです。

  • _where T: struct_-type引数は値型でなければなりません。 Nullable以外の任意の値タイプ-指定できます。詳細については、「 null許容型の使用(C#プログラミングガイド) 」を参照してください。

  • _where T : class_-type引数は参照型でなければなりません。これは、クラス、インターフェイス、デリゲート、または配列型にも適用されます。

  • where T : new()-type引数には、パラメーターなしのパブリックコンストラクターが必要です。他の制約と一緒に使用する場合、new()制約を最後に指定する必要があります。

  • _where T : <base class name>_-type引数は、指定された基本クラスであるか、指定された基本クラスから派生する必要があります。

  • _where T : <interface name>_-type引数は、指定されたインターフェイスであるか、実装されている必要があります。複数のインターフェース制約を指定できます。制約インターフェースは、汎用的なものにすることもできます。

  • _where T : U_-Tに指定されたタイプ引数は、Uに指定された引数であるか、それから派生する必要があります。これはネイキッド型制約と呼ばれます。

これらは次のようにリンクすることもできます:

C#

_public class TestClass<T> where T : MyBaseClass, INotifyPropertyChanged, new() { }
public interface IGenericFace<T> where T : SomeBaseClass
_

VB

_Public Class TestClass(Of T As {MyBaseClass, INotifyPropertyChanged, New})
Public Interface IGenericInterface(Of T As SomeBaseClass)
_
64
Micah

はい。

public interface IGenericFace<T>
    where T : BaseClass
{
}
6
Kip