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){

            }

我对两件事感到困惑。似乎类 T 正在被实例化,但类 T 是一个抽象类。我以为这是不可能的。我认为只能实例化抽象类的非抽象子类。另外,在类中,调用了 makeonemove() ,但是没有参数的版本不是没有被覆盖,因此没有定义吗?在我看来,这段代码不应该编译,但它确实可以。

4

3 回答 3

2

我对两件事感到困惑。似乎类 T 正在被实例化,但类 T 是一个抽象类。我以为这是不可能的。我认为只有子类可以被实例化。

abstract class T没有被实例化,它只是一个指向abstract class.

另外,在类中,调用了 makeonemove() ,但是没有参数的版本不是没有被覆盖吗?在我看来,这段代码不应该编译,但它确实可以。

这是使用抽象类的好处之一。它允许您提供可以在派生类中覆盖的成员的“基本”实现。

于 2012-12-14T02:22:36.483 回答
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 继承的元素。假设我给了 H a函数名为“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 回答
0

不,该类T是抽象的。在方法调用T currentImpl = pendingImpl.Pop();中,T 只是意味着返回的对象将是从 T 派生的类型,它有效地建立(声明)变量 namedcurrentImpl的类型,而不是对象本身的类型。

被实例化的对象的实际类型将是pendingImpl.Pop()创建的任何类型。看起来Pop()就是所谓的工厂方法。您必须查看它是如何实现的,才能准确了解实例化和返回的类型。

于 2012-12-14T02:37:40.140 回答