C# 组件版本控制 new & virtual + override
先看一下三个 C# 关键字对组件版本控制的影响:
virtual:表示这个成员可由派生类型重写override:表示派生类型正在重写基类型的成员new:应用于嵌套类型、方法、属性、事件、常量或字段时,表示该成员与基类中的同名成员无任何关系
示例代码如下:
csharp
using System;
namespace VersionControlSample
{
class Program
{
static void Main(string args)
{
CompanyB.BetterPhone phone = new CompanyB.BetterPhone();
phone.Dial();
Console.ReadLine();
}
}
}
namespace CompanyA
{
class Phone
{
public void Dial()
{
Console.WriteLine("Phone.Dial");
}
}
}
namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public void Dial()
{
Console.WriteLine("BetterPhone.Dial");
base.Dial();
}
}
}这样写编译会出如下警告:
“
CompanyB.BetterPhone.Dial()”隐藏了继承的成员“CompanyA.Phone.Dial()”。如果是有意隐藏,请使用关键字new。
给 BetterPhone.Dial 方法添加 new 关键字,警告就消除了。
csharp
class BetterPhone : CompanyA.Phone
{
public new void Dial()
{
Console.WriteLine("BetterPhone.Dial");
base.Dial();
}
}执行结果为:
BetterPhone.Dial
Phone.Dial看到这里感觉 new 关键字和使用 virtual + override 的功能类似,新的 Dial 方法替代了基类的 Dial 方法,但其实两者有着本质的区别。
new关键字是用来表示该成员(这里是BetterPhone.Dial方法)与基类中同名成员无任何关系;override关键字则是重写基类中同名成员。
在基类 Phone 中加一个虚方法,BetterPhone 中重写该方法。修改后代码如下:
csharp
namespace CompanyA
{
class Phone
{
public void Dial()
{
Console.WriteLine("Phone.Dial");
EstablishConnection();
}
protected virtual void EstablishConnection()
{
Console.WriteLine("Phone.EstablishConnection");
}
}
}
namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public new void Dial()
{
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected override void EstablishConnection()
{
Console.WriteLine("BetterPhone.EstablishConnection");
}
}
}执行结果为:
BetterPhone.Dial
BetterPhone.EstablishConnection
Phone.Dial
BetterPhone.EstablishConnection可以看到 Phone.EstablishConnection 已经被重写了,即使在 Phone.Dial 中调用的也是 BetterPhone.EstablishConnection 方法.
将上面的 override 改成 new virtual ,下面是修改后的代码:
csharp
namespace CompanyB
{
class BetterPhone : CompanyA.Phone
{
public new void Dial()
{
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected new virtual void EstablishConnection()
{
Console.WriteLine("BetterPhone.EstablishConnection");
}
}
}执行结果为:
BetterPhone.Dial
BetterPhone.EstablishConnection
Phone.Dial
Phone.EstablishConnection第四行的输出变成【Phone.EstablishConnection】了,说明调用了基类中的 EstablishConnection 方法。