从非泛型类重写抽象泛型方法

Whi*_*450 6 c# generics overriding abstract

基类

class Drawer
{
    public abstract void Draw<T>(T type);    
}
Run Code Online (Sandbox Code Playgroud)

派生类#1

class ADrawer : Drawer
{
    public override void Draw<T>(List<T> list)
    {
        foreach (var a in list)
        {
            DrawA(a);
        }
    }

    public void DrawA(Agent a)
    {
        //draw code here
    }
}
Run Code Online (Sandbox Code Playgroud)

派生类#2

class AnotherDrawer : Drawer
{
    public override void Draw<T>(T number)
    {
        if (number == 1)
        {
            //draw code
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误发生在#1派生类中:"找不到合适的方法来覆盖"

我应该在基类中使用'virtual'还是'abstract'?

如何设置基本参数类型以允许派生类中的各种参数?

pho*_*oog 10

您的代码存在的问题多于您提出的问题.暂时不考虑覆盖问题,类ADrawer需要一个类型约束(where T : Agent):

class ADrawer : Drawer 
{ 
    public void Draw<T>(List<T> list) where T : Agent
    { 
        foreach (var a in list) 
        { 
            DrawA(a); 
        } 
    }
    public void DrawA(Agent a) 
    { 
        //draw code here 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

没有这个约束,传递a给它是不合法的DrawA,因为a是类型的引用T,没有约束,就没有从类型T到类型的隐式转换Agent.

AnotherDrawer类非法使用==运算符.将==操作符应用于类型T和操作数是不可能的int.你可以通过使用object.Equals覆盖来解决这个问题.

最后,基类有一个错误,因为它是一个包含抽象成员的非抽象类.

但是,一般情况下,此代码表明该类应该是通用的,而不是方法:

abstract class Drawer<T>
{
    public abstract void Draw(T type);
}
Run Code Online (Sandbox Code Playgroud)

派生类#1

class ADrawer : Drawer<List<Agent>>
{
    public override void Draw(List<Agent> list)
    {
        foreach (var a in list)
        {
            DrawA(a);
        }
    }       

    public void DrawA(Agent a)
    {
        //draw code here
    }
}
Run Code Online (Sandbox Code Playgroud)

派生类#2

class AnotherDrawer : Drawer<int>
{
    public override void Draw(int number)
    {
        if (number == 1)
        {
            //draw code
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要跟进Eric Lippert的评论,这也是我对你的问题的第一反应,你可能会考虑这个设计:

abstract class Drawer<T>
{
    public abstract void Draw(T type);
    public void DrawMany(IEnumerable<T> types)
    {
        foreach (var t in types)
            Draw(t);
    }
}
Run Code Online (Sandbox Code Playgroud)

派生类#1

class ADrawer : Drawer<Agent>
{
    public override void DrawA(Agent a)
    {
        //draw code here
    }
}
Run Code Online (Sandbox Code Playgroud)

派生类#2没有变化.


wie*_*ero 5

抽象方法应该有这个signeture

  public abstract void Draw<T>(List<T> type);  
Run Code Online (Sandbox Code Playgroud)