C#:(补)this和base的区别

这一篇是补给C#:类的继承的。

由于在写这篇的时候,发现base和this在访问同一成员的时候编译期提示颜色变成灰色,所以才决定将base和this的区别查一下

微软官方给出的base的介绍其实就是base和this的区别base关键字

调用基类上被其它方法重写的方法--准确来说是在子类中使用base可以调用基类中那个"原生"方法

namespace ExtendsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Shape square = new Square();
            Console.ReadLine();
        }
    }

    class Shape
    {
        public double Area { get; set; }
        public string Color { get; set; }
        //使用virtual表明 该函数成员的功能希望在子类中被更新
        public virtual void ShowInfo()
        {
            Console.WriteLine($"面积:{Area},颜色:{Color}");
        }
    }

    class Square : Shape
    {
        public Square()
        {
            base.ShowInfo();
            this.ShowInfo();
        }
        public override void ShowInfo()
        {
            Console.WriteLine("我是长方形,对边相等且平行...");
        }
    }
}
/*输出:
面积:0,颜色:
我是长方形,对边相等且平行...
*/

base的第一点作用,重在描述base的能力:如果子类重写了父类函数成员,那么在子类中如果不用base,试问还有谁还能访问到基类中那个“原生”方法?(this么?试一下就知道不行--这就是this和base的第一点区别)虽然明白了base有这种作用,但是我却并不知道这个作用在实际编码中有什么用.....

指定创建派生类实例时应调用的基类构造函数

  • 在创建子类实例的时候,由于C#要求必须要先调用基类构造函数,如果基类没有提供构造函数还好(编译器会帮我们隐式调用基类默认构造函数)
  • 但如果基类型没有提供默认构造函数,只是提供了一些带参构造函数,那么编译器可不知道我们要调用哪一个(从下图的报错信息可知:这种情况下编译器不帮我们隐式调用默认构造函数了)
  • 这时base作为拥有"可以在子类中调用基类构造函数"的能力,华丽出场
namespace ExtendsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Shape square = new Square();
            square.ShowInfo();
            Console.ReadLine();
        }
    }

    class Shape
    {
        public double Area { get; set; }
        public string Color { get; set; }
        public Shape(double area)
        {
            this.Area = area;
        }
        public Shape(double area,string color)
        {
            this.Area = area;
            this.Color = color;
        }
        //使用virtual表明 该函数成员的功能希望在子类中被更新
        public virtual void ShowInfo()
        {
            Console.WriteLine($"面积:{Area},颜色:{Color}");
        }
    }

    class Square : Shape
    {
        public Square():base(12.3)//访问基类单参数的构造函数
        {

        }

        public Square(double area,string color):base(area,color)//访问基类两个参数的构造函数
        {

        }
        public override void ShowInfo()
        {
            base.ShowInfo();
            Console.WriteLine("我是长方形,对边相等且平行...");
        }
    }
}
/*输出:
面积:12.3,颜色:
我是长方形,对边相等且平行...
*/

上面展示了base的第二种能力,这勉强算是base和this的第二个区别吧?

成员如果被new修饰,base和this都访问这个成员,此时base、this也是有区别的

namespace ExtendsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Shape square = new Square();
            Console.ReadLine();
        }
    }

    class Shape
    {
        public double Area { get; set; }
        public string Color { get; set; }
        public Shape(double area)
        {
            this.Area = area;
        }

        //使用virtual表明 该函数成员的功能希望在子类中被更新
        public virtual void ShowInfo()
        {
            Console.WriteLine($"面积:{Area},颜色:{Color}");
        }
    }

    class Square : Shape
    {
        public Square() : base(12.3)
        {
            base.ShowInfo();//base已经不是灰色了,表示base和this访问的成员不一样了。
            this.ShowInfo();
        }
        //ShowInfo成员被new修饰,导致这个Square的ShowInfo和Shape的ShowInfo不一致
        public new virtual void ShowInfo()
        {
            Console.WriteLine("我是长方形,对边相等且平行...");
        }
    }
}
/*输出:
面积:12.3,颜色:
我是长方形,对边相等且平行...
*/

如果你看了我写的C#:多态,就知道为什么new会产生如此现象--总之不建议在继承链中使用new,修饰函数成员

非以上描述情况,使用base和this访问同一成员,没有区别:这时base和this可以不写。

namespace ExtendsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Shape square = new Square();
            Console.ReadLine();
        }
    }

    class Shape
    {
        public int cost;
        public double Area { get; set; }
        public string Color { get; set; }
        public Shape(double area)
        {
            this.Area = area;
        }
        public virtual void ShowInfo()
        {
            Console.WriteLine($"面积:{Area},颜色:{Color}");
        }
    }

    class Square : Shape
    {
        public Square() : base(12.3)
        {
            Console.WriteLine(base.cost+"---"+this.cost);//base和this访问数据成员时没有却区别
            Console.WriteLine(base.Area+"---"+this.Area);//base和this访问普通的函数成员时也没有区别
        }
        public override void ShowInfo()
        {
            Console.WriteLine("我是长方形,对边相等且平行...");
        }
    }
}
/*输出:
0---0
12.3---12.3
*/

以上便是对base和this的区别的总结,记录下来以便以后查阅。

posted @   BigBosscyb  阅读(532)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示