Skip to content
标签
欢迎扫码关注公众号

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 方法。

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.