C#易错易混淆知识总结(二)--{构造函数}{this}{枚举}{空指针异常}
一,构造函数
我们先创建一个类,如下面的代码:
class Program { static void Main(string[] args) { } } //创建一个Person类 class Person { }
然后生成代码。
我们使用.NET Reflector反编译该程序集。会发现该类一被编译,CLR会自动的为该类创建一个默认的构造函数。如下图:
所以在创建该对象的时候,会默认的为该类生成一个无参数的空方法体的构造函数。如果我们不显式的写明构造函数,CLR会为我们调用默认的构造函数。
class Person { //声明有实现的构造函数 public Person() { Console.WriteLine("我是超人!"); } }
再次反编译该程序集,会发现添加的构造函数覆盖了C#编译器默认为该类生成的构造函数,如下图:
所以,当程序员手动添加了任意类型的构造函数,C#编译器就不会为该类添加默认的构造函数。
构造函数的特点:
①访问修饰符一般是Public②没有返回值,方法名与类名称一致;
二,This关键字的作用
①this关键字代表当前对象,当前运行在内存中的那一个对象。我们添加如下的代码:
private int nAge; public int NAge { get { return nAge; } set { nAge = value; } } //声明有实现的构造函数 public Person() { this.NAge = 100; Console.WriteLine("我是超人!"); }
这时候我们反编译该程序集,会看到如下结果:
可以看到this关键字代替的就是当前的Person对象。
②一个构造函数后面加“:”符号,后面跟this关键字,可以调用其它的构造函数
三,解析枚举
枚举的级别和类的级别一样,可以自定义数据类型,可以在枚举名称后使用“:”来指明枚举类型。看如下代码:
//定义一个方向的枚举类型,枚举成员使用","分割 enum Direction:string { east, west, south, north }
编译会报错,错误信息如下:
由此我们可以知道枚举的数据类型是值类型。
每一个枚举成员都对应了一个整型的数值,这个数值默认从0开始递增,可以通过强制转换获取该枚举所代表的值。
我们还可以手动为每一个枚举成员赋值,代表的是整型数值,赋值后该枚举成员所代表的值就是所赋的值。
四,空指针异常的问题
首先我们先声明一个Dog类:
class Dog { private int nAge; public int NAge { get { return nAge; } set { nAge = value; } } private string strName; public string StrName { get { return strName; } set { strName = value; } } }
在Main()函数中我们这样调用
Dog d = null; d.StrName = "旺旺";
结果会报错,如下图
我们已经为属性,封装字段了,但是为什么没有办法给字段赋值呢?我们就来探究一下这个问题。
当我们实例化Dog对象,即
Dog d = new Dog();
.NET Framwork做了什么工作呢?如下图:
那为什么会报错呢,原因如下图: