在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近感觉自己C#基础不够扎实,所以又回去看了一些C#的基础知识,这里主要讲解一下比较用的到的this和base的用法。 this是对象级别的使用,指向的是当前实例化的对象,主要有三种用法: 第一种,在实例化构造函数的时候,为了避免传入的参数跟类的字段同名,使用this来区分开,避免混乱。 class MyClass { private int age; private string name; public MyClass(int age, string name) { this.age = age; this.name = name; } } 这里this.age的age是MyClass的字段age。 第二种,在构造函数链里面使用,在类的一个构造函数中,通过this指向一个主构造函数。 这种用法主要是为了避免实例化构造函数需要传入太多参数值。在调用的过程中,先去调用主构造函数,完了以后再调用自己的构造函数。 class MyClass { private int age; private string name; private bool sex; private string address; public MyClass(int age, string name) { this.age = age; this.name = name; } public MyClass(int age, bool sex) 第二个构造函数,传入了age和sex两个参数,在执行的时候会先调用下面的主构造函数,给name,sex和address赋值,完了再回来执行当前的构造函数,给age赋值 第三种是用在扩展方法中,在第一个参数前面加上this,表示对改类型的一个扩展 public static List<ShipMethod> GetSupportedShipMethods(this PlatformType platformType) { List<ShipMethod> methods = null; var log = new LogisticsServiceNameAttribute(); switch (platformType) { case PlatformType.速卖通: methods = Enum.GetValues(typeof(Somitech.Entity.ShipMethod)).Cast<ShipMethod>() .Where(s => s.HasAttribute(typeof(LogisticsServiceNameAttribute)) && !s.HasAttribute(typeof(ObsoleteAttribute)) && s.GetLogisticsServiceName().AliExpress != null).ToList(); break; case PlatformType.敦煌: methods = Enum.GetValues(typeof(Somitech.Entity.ShipMethod)).Cast<ShipMethod>() .Where(s => s.HasAttribute(typeof(LogisticsServiceNameAttribute)) && !s.HasAttribute(typeof(ObsoleteAttribute)) && s.GetLogisticsServiceName().DhGate != null).ToList(); break; default: throw new NotImplementedException(platformType.ToString()); } methods = methods.ToList(); return methods; }
base是类级别的,指向基类,比较常用的用法也有两种: 第一种,在派生类的构造函数中调用基类的构造函数。 我们知道在派生类的实例化过程中,会先去调用基类的构造函数,正常是调用默认构造函数,这里我们可以指定调用哪个构造函数。 执行顺序是,先执行基类的带参数的构造函数,然后再执行派生类的构造函数。 public class MyBaseClass { public MyBaseClass() { Console.WriteLine("基类无参构造函数!"); } public MyBaseClass(int num) { Console.WriteLine("基类带有整型参数的构造函数!"); } } public class MyClass : MyBaseClass { public int age; public MyClass() { } //派生类调用基类带参数的构造函数,这里会调用MyBaseClass(int num)这个方法 public MyClass(int num) : base(num) { age = 102; Console.WriteLine("派生类带有整型参数的构造函数!age=" + age); } } 在MyClass类的构造函数MyClass(int num)被调用的时候,会先去调用基类中的构造函数MyBaseClass(int num) 第二种,在派生类的方法中调用已经被重写的基类的方法。 public class MyBaseClass { public MyBaseClass() { Console.WriteLine("基类无参构造函数!"); } public MyBaseClass(int num) { Console.WriteLine("基类带有整型参数的构造函数!"); } public virtual void GetMyAge() { Console.WriteLine("我是基类,我的年龄最大!"); } } public class MyClass : MyBaseClass { public int age; //派生类调用基类带参数的构造函数,这里会调用MyBaseClass(int num)这个方法 public MyClass(int num) : base(num) { age = 102; Console.WriteLine("派生类带有整型参数的构造函数!age=" + age); } public override void GetMyAge() { 这里,我们再子类的GetMyAge方法中通过base.GetMyAge()来调用基类的被重写的方法,执行完基类方法以后,再执行方法剩下的部分。 会输出: 我是基类,我的年龄最大! 我是派生类,我的年龄比较小!
最后,我们再通过一个控制台项目来结合this和base的用法使用一下,在控制台输入以下代码: 新建一个MyBaseClass的基类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignPatterns.Basic { public class MyBaseClass { public MyBaseClass() { Console.WriteLine("基类无参构造函数!"); } public MyBaseClass(int num) { Console.WriteLine("基类带有整型参数的构造函数!"); } public virtual void GetMyAge() { Console.WriteLine("我是基类,我的年龄最大!"); } } } 再新建一个子类MyClass: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignPatterns.Basic { public class MyClass : MyBaseClass { public int age; public static int age2; public static readonly object obj = new object(); static MyClass() { age2 = 100; Console.WriteLine("执行静态构造函数!age2=" + age2); } public MyClass() : this(5) { age = 101; Console.WriteLine("派生类无参构造函数!age=" + age); } public MyClass(int num) : base(num) { age = 102; Console.WriteLine("派生类带有整型参数的构造函数!age=" + age); } public MyClass(int num, int kit) { Console.WriteLine("派生类带有两个参数的构造函数"); } public override void GetMyAge() { base.GetMyAge(); Console.WriteLine("我是派生类,我的年龄比较小!"); } } } 最后在Program文件的Main函数中输入以下代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DesignPatterns.Basic; namespace DesignPatterns { class Program { static void Main(string[] args) { //执行顺序是:静态构造函数 =》 基类带有参数的构造函数 =》派生类带有参数的构造函数 =》派生类无参构造函数 MyClass myClass = new MyClass(); //执行顺序是:基类带有参数的构造函数 =》 派生类带有参数的构造函数 MyClass myClass1 = new MyClass(10); Console.ReadKey(); } } } 在这里,我们在子类中添加了三个字段,一个普通字段age,两个静态字段age2和obj,这里先讲讲静态字段的用法。 静态字段跟静态方法一样是通过类来调用的,所有的对象共享这个静态字段,这个字段一旦被初始化以后就不能再次赋值了,我们可以在申明的时候就去初始化,比如obj。如果在申明的时候没有初始化,那只能通过静态构造函数去初始化,比如age2。 一个类中如果存在静态构造函数,那么静态构造函数会被优先调用,而且只会被执行一次,真实的执行过程是:每次执行实例化构造函数的时候,都会去判断静态构造函数是否有被执行,如果没有就执行优先执行静态构造函数,如果执行了,就不再去执行。 所以在执行下面这个代码的时候,其实走了4步:MyClass myClass = new MyClass(); 首先调用静态构造函数,给静态变量age2赋值,然后调用派生类的构造函数public MyClass() : this(5),但是因为这个构造函数通过this指向了主构造函数,所以需要先去调用主构造函数public MyClass(int num) : base(num),而主构造函数又通过base去调用了基类的带参数的构造函数public MyBaseClass(int num),执行顺序是:静态构造函数 =》 基类带有参数的构造函数 =》派生类带有参数的构造函数 =》派生类无参构造函数 正确的输出: 在执行MyClass myClass1 = new MyClass(10);这个方法的时候就简单多了,因为静态构造函数上面已经执行了,所以这里就不再执行。 顺序:基类带有参数的构造函数 =》 派生类带有参数的构造函数 以上就是大概base和this的用法了,这两个的用法主要都是为了方便我们少写一些代码。 |
请发表评论