overriding abstract generic method from non generic class

瘦欲@ 提交于 2019-12-10 13:28:44

问题


base class

class Drawer
{
    public abstract void Draw<T>(T type);    
}

derived class #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
    }
}

derived class #2

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

The error is in the #1 derived class : "no suitable method found to override"

Should I be using 'virtual' in the base class as well as 'abstract' ?

How should I set the base parameter type to allow a variety of parameters in derived classes?


回答1:


Your code has more problems than just the one you ask about. Setting aside the override question for the moment, class ADrawer needs a type constraint (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 
    } 
} 

Without that constraint, it's not legal to pass a to DrawA, because a is a reference of type T, and without the constraint there is no implicit conversion from type T to type Agent.

The AnotherDrawer class has an illegal use of the == operator. It's not possible to apply the == operator to operands of type T and int. You could get around that by using the object.Equals override.

Finally, the base class has an error because it is a non-abstract class containing an abstract member.

In general, however, this code indicates that the class should be generic, rather than the method:

abstract class Drawer<T>
{
    public abstract void Draw(T type);
}

derived class #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
    }
}

derived class #2

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

To follow up on Eric Lippert's comment, which was also my first reaction to your question, you might consider this design instead:

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

derived class #1

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

Derived class #2 is unchanged.




回答2:


abstract method should have this signeture

  public abstract void Draw<T>(List<T> type);  



回答3:


To get it to compile change the base class to this:

class Drawer
{
    public abstract void Draw<T>(List<T> type);    
}

List<T> is not the same as T, so when you pass in a List<T> in the derived class' method you can't override the base method as that has a T parameter, not a List<T> parameter.



来源:https://stackoverflow.com/questions/9197384/overriding-abstract-generic-method-from-non-generic-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!