Overriding an abstract generic method from a non-generic class

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 } } } 

Error in derived class # 1: "no suitable method to override"

Should I use "virtual" in the base class as well as "abstract"?

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

+4
source share
3 answers

Your code has more problems than just the one you are asking about. Canceling the issue of overrides at the moment, the ADrawer class 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 this restriction, it is not allowed to pass a to DrawA because a is a reference of type T , and without restriction there is no implicit conversion from type T to type Agent .

AnotherDrawer class has illegal use of the == operator. It is not possible to apply the == operator to operands of type T and int . You can get around this by overriding object.Equals .

Finally, the base class has an error because it is not an abstract class containing an abstract element.

In general, however, this code indicates that the class should be generic, not a 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 Eric Lippert's comment, which was also my first reaction to your question, you can think of this design:

 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 does not change.

+7
source

abstract method must have this sign

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

To get it for compilation, change the base class to this:

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

List<T> does not match T , so when you pass the List<T> method in a derived class, you cannot override the base method because it has the parameter T , not List<T> .

+1
source

Source: https://habr.com/ru/post/1395440/


All Articles