1
public abstract class T
{
    public abstract IEnumerable<T> MakeOneMove();

    public IEnumerable<T> MakeOneMove(string evt)
    {
        List<T> returnList = new List<T>();
        IEnumerable<T> steps = MakeOneMove();
        foreach (T step in steps)
        {
            if (step.Event == evt)
            {
                returnList.Add(step);
            }
        }
        return returnList;
    }

他の場所では、クラスは次のように使用されます。

            T currentImpl = pendingImpl.Pop();

            IEnumerable<T> nextImpl = currentImpl.MakeOneMove();
            foreach (ConfigurationBase next in nextImpl){

            }

私は2つのことについて混乱しています。クラス T がインスタンス化されているようですが、クラス T は抽象クラスです。これはありえないと思いました。抽象クラスの非抽象サブクラスのみがインスタンス化できると考えていました。また、クラス内で makeonemove() を呼び出していますが、引数のないバージョンはオーバーライドされていないため定義されていないのではないでしょうか? このコードはコンパイルされないように思えますが、それでもコンパイルされます。

4

3 に答える 3

2

私は2つのことについて混乱しています。クラス T がインスタンス化されているようですが、クラス T は抽象クラスです。これはありえないと思いました。インスタンス化できるのはサブクラスだけだと思っていました。

abstract class Tはインスタンス化されていません。むしろ、の具体的な実装への単なるポインタabstract classです。

また、クラス内でmakeonemove()を呼び出していますが、引数なしのバージョンはオーバーライドされていないのでしょうか?このコードはコンパイルされないように思えますが、それでもコンパイルされます。

これは、抽象クラスを使用する利点の 1 つです。派生クラスでオーバーライドできるメンバーの「基本」実装を提供できます。

于 2012-12-14T02:22:36.483 に答える
0

いいえ、クラスTは抽象的です。Tを呼び出すメソッドT currentImpl = pendingImpl.Pop();では、返されるオブジェクトがTから派生する型になることを意味し、currentImplオブジェクト自体の型ではなく、という名前の変数の型を効果的に確立(宣言)します。

インスタンス化されるオブジェクトの実際のタイプは、pendingImpl.Pop()作成されるタイプになります。Pop()いわゆるファクトリメソッドのようです。どのタイプがインスタンス化されて返されるかを正確に確認するには、それがどのように実装されているかを確認する必要があります。

于 2012-12-14T02:37:40.140 に答える
0

いいえ、T はクラスが T に変換可能でなければならない (つまり、クラスから継承され、T としてキャストできる) ことを意味します。

ここで継承について確認することをお勧めします: http://www.csharp-station.com/Tutorial/CSharp/lesson08

キャストについては、こちらをご覧ください: http://csharp-station.com/Tutorial/CSharp/Lesson22

基本的に、あるクラスが別のクラスを継承する場合、そのクラスはそのクラスのインスタンスにキャストできるため、キャストのクラスとして扱われます。

たとえば、T から継承したクラス H を作成し、それを T にキャストするとします。そのキャストの間、H は基本的に T に偽装され、T から継承した要素にしかアクセスできませんでした。関数を「MakeTwoMoves」と呼び、次に「hi」と呼ばれる H のインスタンスを作成します (例: H hi = new H();)。MakeOneMove と MakeTwoMoves を呼び出すことができます。ただし、T にキャストされると (たとえば (T)H)、MakeTwoMoves は T で宣言されていないためアクセスできなくなります。これは H に固有のものです。

ただし、コードにとってこれが意味することは、 pendingImpl には T から継承されたクラスのインスタンスの配列が含まれる可能性が最も高いということです (私の例の H のように)。その後、それらは pop メソッド内で (またはそれより前に、つまり内部配列に配置される前に) キャストされ、T として出力されるため、各インスタンスは完全に異なるクラスになる可能性がありますが、それらについて知っている唯一のことは、それらがから継承されていることです。 T.

T は、作業するのに最も直感的な名前ではありません。

于 2012-12-14T04:15:15.087 に答える