class Drawer
{
public abstract void Draw<T>(T type);
}
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
}
}
class AnotherDrawer : Drawer
{
public override void Draw<T>(T number)
{
if (number == 1)
{
//draw code
}
}
}
错误发生在#1派生类中:“找不到合适的方法来覆盖”
我应该在基类中使用'virtual'还是'abstract'?
如何设置基本参数类型以允许派生类中的各种参数?
答案 0 :(得分:8)
您的代码存在的问题多于您提出的问题。暂时不考虑覆盖问题,类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
}
}
如果没有这种约束,将a
传递给DrawA
是不合法的,因为a
是T
类型的引用,没有约束就没有隐式转换从类型T
到类型Agent
。
AnotherDrawer类非法使用==
运算符。无法将==
运算符应用于T
和int
类型的操作数。您可以使用object.Equals
覆盖来解决这个问题。
最后,基类有一个错误,因为它是一个包含抽象成员的非抽象类。
但是,一般情况下,此代码表示类应该是通用的,而不是方法:
abstract class Drawer<T>
{
public abstract void Draw(T type);
}
派生类#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
}
}
派生类#2
class AnotherDrawer : Drawer<int>
{
public override void Draw(int number)
{
if (number == 1)
{
//draw code
}
}
}
要跟进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);
}
}
派生类#1
class ADrawer : Drawer<Agent>
{
public override void DrawA(Agent a)
{
//draw code here
}
}
派生类#2没有变化。
答案 1 :(得分:5)
抽象方法应该有这个signeture
public abstract void Draw<T>(List<T> type);
答案 2 :(得分:1)
要使其编译,请将基类更改为:
class Drawer
{
public abstract void Draw<T>(List<T> type);
}
List<T>
与T
不同,因此当您在派生类'方法中传入List<T>
时,您无法覆盖基本方法,因为它具有T
1}}参数,而不是List<T>
参数。