对泛型如何与继承一起使用感到困惑

Aiy*_*uni -2 c#

我试图在工作中重构一些代码,但遇到了一些问题。假设我有以下代码(为说明问题而进行了大大简化):

抽象的Row类:

abstract class Row 
{

}

Run Code Online (Sandbox Code Playgroud)

扩展Row的具体Row类

class SpecificRow : Row
{

}
Run Code Online (Sandbox Code Playgroud)

一个接口,该接口采用带有接受ICollection的方法的通用类型:

interface IDbInsertable<T> 
{
   void InsertToDb(ICollection<T> list);
}

Run Code Online (Sandbox Code Playgroud)

实现上述接口的抽象类:

abstract class BaseDownloader: IDbInsertable<Row>
{
   public abstract void InsertToDb(ICollection<Row> list);
   //and other unrelated methods...
}
Run Code Online (Sandbox Code Playgroud)

扩展BaseDownloader的具体类:

class SpecificDownloader : BaseDownloader 
{
  public void InsertToDb(ICollection<SpecificRow> list)
  {
     //implementation
  }
  //other stuff
}
Run Code Online (Sandbox Code Playgroud)

在SpecificDownloader类中,出现错误“ SpecificDownloader未实现继承的抽象成员' BaseDownloader.InsertToDb(ICollection<Row>)

我尝试过的

  1. 保存所有代码并重新编译
  2. 更改public void InsertToDb()public override void InsertToDb(),在这种情况下,错误消息将变为“ SpecificDownloader.InsertToDb没有找到要覆盖的合适方法”。
  3. 重新启动Visual Studio

从理论上看,以上内容在我看来应该可以很好地工作,但这并不是让我编译,也没有理由。如果我错过了重要的事情,请告诉我。

小智 5

Make BaseDownloader a generic class. and add a type constraint that forces T to be a type of row. Like this

//Class implements the interface and uses the Generic type T from basedownloader. And that has the type constraint
abstract class BaseDownloader<T> : IDbInsertable<T> where T : Row
{
    //This forces T to always be a type row
    public abstract void InsertToDb(ICollection<T> list);
    //and other unrelated methods...
}
Run Code Online (Sandbox Code Playgroud)

And then when inheriting from basedownloader specify the type of row you desire. Like this

//Class now gives specificrow as the generic type when inheriting from basedownloader
class SpecificDownloader : BaseDownloader<SpecificRow>
{
    //Now InsertToDb has a collection of SpecificRow instead of just row
    public override void InsertToDb(ICollection<SpecificRow> list)
    {
        //implementation
    }
    //other stuff
}
Run Code Online (Sandbox Code Playgroud)

More on generic type constraints