由于类的多态属性,下面的示例将打印AB
两次,这是预期的。
在我的情况下,我真的希望它打印A
然后AB
。
我决定将Get()
中的B
方法从overrides
更改为new
。
这解决了我的问题,但他们告诉我不好的做法,所以我正在寻找替代方案...
我想到的一件事是instantiate a new A in B.Do()
,我认为这也是不好的做法......
//ORIGINAL
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return base.Get() + "B";
}
}
//UPDATED, USING NEW
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
Console.ReadLine();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public new string Get()
{
return base.Get() + "B";
}
}
答案 0 :(得分:0)
您可以按以下方式更改实施,而不是在Do
中调用B.Do
的基本版本:
public class B : A
{
public override void Do()
{
// Call the base version of Get explicitly
var getBase = base.Get();
Console.WriteLine(getBase);
// Call the current implementation of Get
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return "B";
}
}
这将在技术上解决您的问题,但从OOP的角度来看,这不是一个非常干净的解决方案。我建议您考虑是否需要能够独立覆盖Get
。也许更改方法的签名以便Get
始终返回应打印的字符串列表也是一个很好的解决方案(我已将Get
重命名为GetLines
以反映更改后的目的方法):
public class A
{
public virtual void Do()
{
var lines = GetLines();
foreach(var line in lines)
Console.WriteLine(line);
}
public virtual IEnumerable<string> GetLines()
{
return new string[] { "A" };
}
}
public class B : A
{
public override IEnumerable<string> GetLines()
{
var lst = new List<string>(base.GetLines());
lst.Add("B");
return lst;
}
}
答案 1 :(得分:0)
以下是更正后的代码:
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
Console.WriteLine(Get());
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
Console.WriteLine(base.Get());
base.Do();
}
public override string Get()
{
return base.Get() + "B";
}
}