c#泛型和继承

Ste*_*ens 1 c# generics inheritance

我在以下代码上遇到编译错误:

public abstract class DbHandler<T>
{
    public abstract bool Save(T obj);
    ...
}
Run Code Online (Sandbox Code Playgroud)

及其实施类:

 public class SpaghettiTableDb : DbHandler<SpaghettiTable>
 {
    public bool Save(SpaghettiTable obj)
    {
        return false;
    }
    ...
 }
Run Code Online (Sandbox Code Playgroud)

错误是:

'SpaghettiTableDb' does not implement inherited abstract member 'SeatPicker.DbHandler<SeatPicker.SpaghettiTable>.Save(SeatPicker.SpaghettiTable)'
Run Code Online (Sandbox Code Playgroud)

但我认为确实如此,所以我不确定为什么我收到这个错误.

(SpaghettiTable只是一个具有一些属性的类,仅此而已)

有帮助吗?

Chr*_*air 5

您需要使用override关键字.否则,您没有实现抽象基类,只是在子类上创建一个"新的"单独方法.

public override bool Save(SpaghettiTable obj)
{
    return false;
}
Run Code Online (Sandbox Code Playgroud)

想想abstract方法就像virtual你重写的方法一样.唯一的区别是您强制子类提供该方法的实现,而virtual方法提供了自己的实现,子类可以选择覆盖它们自己的实现.

编辑:此外,如果你想在Visual Studio中让你的生活更轻松,你可以右键单击(或ctrl+.)继承声明并选择"实现抽象类"(或类似的东西,我没有VS和我一样) now)将自动为您创建所有重写的方法.

public class SpaghettiTableDb : DbHandler<SpaghettiTable> //right-click on "DbHandler"

或者,在类中的空代码空间中,您可以开始键入"覆盖",然后IntelliSense将列出基类中的所有可覆盖成员,当您选择一个时,它将自动为您编写默认实现.

编辑:只是为了扩展你的代码,没有override关键字,你创建一个属于你的子类而不是覆盖基类的新方法.当您从使用基类的上下文调用该方法时,它不会调用您的子类实现,因为它不会覆盖基本方法.

考虑以下类.(我使用虚拟而不是抽象,因此它编译并使其更简单)

public class BaseClass
{
    public virtual void Print()
    {
        Console.WriteLine("base print");
    }

    public virtual void AnotherPrint()
    {
        Console.WriteLine("base another print");
    }
}

public class SubClass : BaseClass
{
    public override void Print()
    {
        Console.WriteLine("sub print");
    }

    public void AnotherPrint()
    {
        Console.WriteLine("sub another print");
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,SubClass.AnotherPrint不会覆盖BaseClass.AnotherPrint.

当您使用以下代码时:

SubClass mySub = new SubClass();

mySub.Print(); //sub print
mySub.AnotherPrint(); //sub another print

BaseClass myBase = mySub;

myBase.Print(); //sub print
myBase.AnotherPrint(); //base another print
Run Code Online (Sandbox Code Playgroud)

需要注意的是通过代码,mySub并且myBase都指向同一个对象,但一个是类型为SubClass和其他作为BaseClass.当运行时调用时myBase.Print(),它可以轻松检查类的继承,并查看它SubClass已覆盖Print方法并调用SubClass实现.但是,由于SubClass.AnotherPrint没有明确标记override,运行时/编译器认为这是一个完全不同的方法,没有链接到该BaseClass.AnotherPrint方法.因此,运行时坚持基类实现.当你的实例被输入时SubClass,编译器确实会看到你指向那个新方法而且基本上没有指向基本实现.