web-dev-qa-db-ja.com

C#ジェネリックス:Tを制約するここでT:オブジェクトはコンパイルされません。エラー:制約を特別なクラス 'オブジェクト'にすることはできません

Tを次のように制約すると:次のようなオブジェクト:

public interface IDoWork<T> where T : Object
{
    T DoWork();
}

エラーが発生します:

制約を特別なクラス 'オブジェクト'にすることはできません

それは、コンパイルする以下のものとの暗黙の違いがあることを意味しますか?

public interface IDoWork<T> // where T : Object
{
    T DoWork();
}
20

2つの制約の間に違いはありませんが、明示的に述べるのが役に立たないために1つが許可されていない点が異なります。

C#4.0言語仕様(10.1.5型パラメーターの制約)では、これについて2つのことが述べられています。

タイプはオブジェクトであってはなりません。すべてのタイプはオブジェクトから派生するため、許可されている場合、このような制約は効果がありません。

.。

Tに主要な制限または型パラメーターの制約がない場合、その有効な基本クラスはオブジェクトです。

コメントで、TVoidタイプにしようとしているとおっしゃいました。 Voidは、戻り値の型がなく、適切な具象型を必要とするTの代わりに使用できないことを示す特殊な型です。メソッドのvoidバージョンと、両方が必要な場合はTバージョンを作成する必要があります。

15
Chris Hannon

ジェネリック型を参照型に制約する場合は、: classを使用します。

public interface IDoWork<T> where T : class
{
    T DoWork();
}

これにより、ジェネリック型がintや構造体などの値型になることが禁止されます。

51
Douglas

C#4.0言語仕様(コード化:[10.1.5]型パラメーターの制約)によると、次の2つのことがわかります。

1]型はオブジェクトであってはなりません。すべてのタイプはオブジェクトから派生するため、許可されている場合、このような制約は効果がありません。

2] Tに主要な制限または型パラメーターの制約がない場合、その有効な基本クラスはオブジェクトです。

ジェネリッククラスを定義するとき、クライアントコードがクラスをインスタンス化するときに型引数に使用できる型の種類に制限を適用できます。クライアントコードが制約で許可されていない型を使用してクラスをインスタンス化しようとすると、コンパイル時エラーが発生します。これらの制限は制約と呼ばれます。制約は、wherecontextualキーワードを使用して指定されます。 ジェネリック型を参照型に制約する場合は、:classを使用します。

[〜#〜] msdn [〜#〜] によると

制約を特別なクラス「識別子」にすることはできません。次のタイプは制約として使用できません。

  • System.Object
  • System.Array
  • System.Delegate
  • System.Enum
  • System.ValueType。
0
Rahul Nikate