web-dev-qa-db-ja.com

C#4.0では、ジェネリック型パラメーターからクラスを派生させることは可能ですか?

私はこれを試してきましたが、これを理解できないようです。これをやりたい...

public abstract class SingletonType<TSingleton, TBaseClass> : TBaseClass
    where TSingleton : TBaseClass, new()
    where TBaseClass : class
{
    static TSingleton _singleton;
    public static TSingleton Singleton
        => _singleton ?? (_singleton = new TSingleton());
}

計画は、このように使用して、基本クラスの周りにシングルトンパターンを「ラップ」することでした...

public class SingletonFoo : SingletonType<SingletonFoo, Foo> {
}

しかし、私はこれを取得し続けます

タイプパラメータであるため、「TBaseClass」から派生できません

ええと...タイプはまさにあなたが派生したものだと思いましたdo

だから私は何が欠けていますか?

注:これはもちろん、何も役に立たないので簡単な例ですが、SingletonTypeには質問に関係のない他のロジックがたくさんあると仮定します。したがって、手元の質問に焦点を合わせるために省略されています。

24
Mark A. Donohoe

いいえ、これは不可能です。たとえば、sealedと宣言されている型を考えてみましょう。そのクラスから継承することはできません。また、封印されていない型に制限する制約はありません。ジェネリックパラメーターを介して継承しようとするエルゴは不可能です。

18
Tejs

C#のジェネリック型はC++テンプレートではありません。ジェネリック型はすべての可能な型引数に対して機能する必要があることを忘れないでください。テンプレートは、実際に作成した構造に対してのみ機能する必要があります。

この質問は重複しています。に対する私の答えを参照してください

C#ジェネリックがC++テンプレートのようにジェネリック型パラメーターの1つから派生できないのはなぜですか?

これについてのより多くの考えのために。基本的に、簡単な答えは、かなりのコストが機能の小さな利点を上回らないということです。その答えが気に入らない場合は、私の2番目の答えを参照してください。

C#ジェネリックがC++テンプレートのようにジェネリック型パラメーターの1つから派生できないのはなぜですか?

また、その回答が気に入らない場合は、フォローアップの質問を参照してください。

。NETジェネリックがジェネリックパラメータータイプの1つを継承できることを望む正当な理由は何ですか?

27
Eric Lippert

ジェネリックが含まれている場合でも、すべての型には正確に1つの個別の親クラスがあります。オープンジェネリック型(typeof(List<>)など)を処理する場合でも、親クラスを見つけることができます。

あなたが望むものが許可された場合、これは真実ではないでしょう、typeof(SingletonType<,>には親タイプがなく、これは許可されていません。

1
David Yaw

いいえ、それは不可能です。あなたがこのクラスを持っているとしましょう:

class bar {
  int example = 0;
}

これがタイプパラメータクラスです。

class foo<T> : T {
  int example = 5;
}

タイプfoo<bar>の変数を作成した場合、exampleは混同されます。

0
facepalm42