C# 组件版本控制 new
& virtual
+ override
🏷️ C#
先看一下三个 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
方法。