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作为拥有"可以在子类中调用基类构造函数"的能力,华丽出场
    C#:(补)this和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的区别的总结,记录下来以便以后查阅。