我这人就爱较真儿。今天八卦一下C#的构造函数: (一)先看一下引用类型的实例构造函数(ctor): 测试一,无参ctor: 只要是程序员,都这么写过代码。我们甚至可以省略B和A的无参ctor,但是,在CLR内部,会默认为B和A创建各自的默认无参ctor(啥事儿也不做),new B的时候,一级级从子孙向祖先往上冒,直到所有类的基类:Object的ctor。 当我们在Visual Studio中创建一个窗体的时候,对下面的代码是习以为常的: public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
习惯最可怕,它会让你迷失自我,不相信?看下面的测试:
测试二,把B中的无参ctor修改为有参ctor:
编译不能通过,错误如上图所示。有人说了,B不是有默认构造函数么?俄,看起来,只能由CLR内部使用哦,我们想要用,没戏。
如果想创建上述的B对象,必须这么写:
int v = 10;
B b = new B(v);
有人会问,B的ctor为什么不写成:
就是说,为什么不用base。我说不用,因为此时A中只有一个无参ctor,所以,不管B中加不加base,都会调用A的这个无参ctor。
测试三,如果A中有2个ctor:
这时,B的ctor仍然会调用A的默认无参ctor,不信你就debug试试。
如果此时B的ctor是有参的,仍然会调用A的默认无参ctor,谁叫你不给B的ctor加base的呢:
最后介绍最正规的做法:
说到底,就是默认构造函数的有无在作祟,没啥道理可言,因为都是C# Team制定的规则,如果不小心写错了,编译器第一个会报错,所以不怕工作中出错,也就面试的时候会被搞死。
(二)然后恶搞值类型的实例构造函数(ctor),说实话,我很烦它,胜过static类,因为从来没有在项目中自定义过struct,但是每次总结C#语法,它和static都是特例。但static类我起码在Silverlight中Command中经常写。
测试一:
这么玩的结果就是,struct中所有的成员都是0或null,可是这样的对象,我们真的需要吗?
所以,接下来,你还要手动设置struct中的各个属性:
SomeValueType b = new SomeValueType() { y = 2 };
b.x = 1;
娃哈哈,struct居然支持C# 3.0新语法,刮目一个。
此外,你还会发现,struct中也可以有引用类型的成员,没见过这么玩的吧?反正我做了5年也没见过哪个项目这么搞。
测试二:
如果你要使用struct的无参ctor,千万别在struct中声明无参ctor,不信你就试试,如下所示:
测试三:
看来还是做一个有参数的ctor比较靠谱:
但是,struct中所有的变量,都要在有参ctor中进行初始化,不信那个邪,少一个就搞死你,如下所示:
测试四:
你要是敢这么写:
就相当于没看懂我这篇文章,请 goto 测试一。
(三)最后,yy一下类的ctor。我习惯称其为cctor。
cctor只允许存在一个无参cctor,而且还不能带有访问修饰符(例如private),默认为private的(但就是不让你指定private):
说白了,cctor就是用来实例化类中那些静态成员的。而且是一次性的,仅在类创建(new)的时候(而不是声明的时候)执行。
调试上面的例子,我们会发现,a先等于1,后等于3,这说明static内联赋值要比cctor还要早。
话说,cctor可以用于引用类型/值类型,但在值类型中定义cctor是没有意义的。看过上文就会知道,值类型是没有机会执行cctor的。
cctor的调用过程如下:
编译时,JIT编译器将检查AppDomain是否执行了cctor(有记录的),以决定是否生成调用代码;
执行时,如果有多个线程,则需要一个互斥的线程同步锁,以确保只执行一次cctor。
cctor位于AppDomain中,因此不支持静态的Finalize()方法,就是说对GC免疫。
cctor不会调用其基类的cctor,两者是没有关系的。
本来cctor是非常简单的,但和“实例”混在一起的时候,就很容易混淆了。
静态变量和实例变量并不是一对反义词。
1)实例方法中可以使用静态成员/方法。
2)静态方法中不能使用定义在该静态方法外的实例成员
3)但在静态方法中,可以使用定义在该静态方法内的实例成员
4)永远的特例——Main函数
class A
{
private static int a = 1;
static A()
{
a = 3;
}
public string b = "bjq";
public A()
{
a = 2;
}
static void Main(string[] args)
{
Console.WriteLine(a);
}
}
|
请发表评论