3

次のことを考慮してください。

public class EntityBase<TEntity>
{
    public virtual void DoSomethingWhereINeedToKnowAboutTheEntityType()
    {
    }
}

public class PersonEntity : EntityBase<PersonEntity>
{
    public override void DoSomethingWhereINeedToKnowAboutTheEntityType()
    {
    }
}

これをコードに追加して実行すると、問題なく動作しましたが、継承するクラスに基づいた定義のクラスを継承できることに驚いています。

私がそれを試したとき、私はそれがコンパイルされないか、実際に呼び出されたら失敗することを期待していました。

あなたはインターフェースで同様のことをすることができます:

public interface IEntityBase<TEntity>
{}

public class PersonEntity : IEntityBase<PersonEntity>
{}

私は実際にインターフェースを使用して前者から後者にコードを切り替えましたが、なぜこれが機能するのかまだ興味があります。

4

3 に答える 3

4

うまくいかない理由がないからうまくいく。EntityBase<PersonEntity>から継承せずPersonEntity、型を参照するだけです。基本クラスが独自の派生クラスを認識していても、技術的な問題はありません。これも機能します (この特定の例は悪い考えですが):

public class A
{
    public B AsB()
    {
        return this as B;
    }
}


public class B : A
{
}
于 2012-08-17T12:15:44.873 に答える
3

継承クラスに基づいた定義のクラスを継承できることに驚いています。

注意-継承しているのは、定義に任意Typeのが含まれるクラスです。これらはすべて合法です。

class O : EntityBase<object>
class S : EntityBase<String>
class Q : EntityBase<Q>

の定義であなたが言ったことは、それは型EntityBaseであるTEntityべきだということだけです-まあ、PersonEntityですよね?では、なぜそれが資格を得る資格がないのTEntityですか?理由はありません-それで動作します。

定義の順序について心配するかもしれませんが、コンパイルの単位内では、すべてが「一度に」定義されることを覚えておいてください-PersonEntity他の何か(それ自体を含む!)がそれを参照する前に「コンパイルする必要がある」という意味はありません。確かに、あなたも許可されています

class A : EntityBase<B>
class B : EntityBase<A>

そのようなことが必要な場合、考えられる「コンパイルの順序」は機能しません。

于 2012-08-17T12:26:12.893 に答える
1

非常に単純な例は、汎用インターフェースIComparable<T>です。通常、次のように実装します。

class MyClass : IComparable<MyClass> {/*...*/}

ジェネリックテンプレートのこの実装は、MyClassオブジェクトが他のオブジェクトと比較できることを示していMyClassます。ご覧のとおり、メンタルモデルに問題はありません。クラスについて何も知らなくても、オブジェクトを比較できるクラスの概念をよく理解できます。

ここでの重要な点は、テンプレートパラメータはジェネリッククラスまたはインターフェイスによって使用されるだけですが、継承によって関連付けられる必要はまったくないということです。IComparable<MyClass>から継承しませんMyClass。したがって、循環性はありません。

于 2012-08-17T12:26:51.550 に答える