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(),但是不是没有被覆盖的参数的版本,因此没有定义?在我看来,这个代码不应该编译,但确实如此。
答案 0 :(得分:2)
我对两件事感到困惑。好像是T级 instanced,但是T类是一个抽象类。我以为这不是 可能。我以为只有子类可以实例化。
abstract class T
没有被实例化,而只是指向abstract class
的具体实现的指针。
另外,在 class,makeonemove()被调用,但不是没有的版本 参数没有被覆盖?在我看来,这样的代码不应该 编译,但确实如此。
这是使用抽象类的好处之一。它允许您提供其成员的“base”实现,可以在派生类中重写。
答案 1 :(得分:0)
不,班级T
是抽象的。在方法中调用T currentImpl = pendingImpl.Pop();
T只是意味着返回的对象将是一个派生自T的类型,它有效地建立(声明)名为currentImpl
的变量的类型,而不是类型对象本身。
要实例化的对象的实际类型将是pendingImpl.Pop()
创建的任何类型。看起来Pop()
就是所谓的工厂方法。您必须查看它是如何实现的,以确切地查看实例化和返回的类型。
答案 2 :(得分:0)
不,T只是意味着该类必须可以转换为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一个名为'MakeTwoMoves'的函数,然后创建了一个名为'hi'的H实例(例如H hi = new H();)我可以调用MakeOneMove和MakeTwoMoves。然而,一旦它被转换为T(例如(T)H),你就不再可以访问MakeTwoMoves,因为它没有在T中声明,它是H独有的东西。
这对您的代码意味着,pendingImpl很可能包含从T继承的类的实例数组(如我的示例中的H)。然后将它们转换为pop方法(或者可能更早,即放入内部数组之前)并以T形式出现,因此每个实例可能是一个完全不同的类,但你唯一知道的是它们继承自吨。
我希望稍微清楚一点,T不是最直观的名称。