关于“构造函数”中的几个小问题,或许面试会问到哦~

构造函数这玩意也是面试官常常会问到的东西。我们知道一个类的状态初始化就全靠它了,以下提几个小问题。

Q:我看到Web项目里面通常都有一个BasePage页面,当中构造函数里面做了权限验证。

     请问为什么要这么做。

A:  既然这么做了,那么设计者肯定就知道了一个原则就是实例构造器中。父类构造器先于子类运行,那么这个先运行就可

     以做非常多有意思的事情,比方你说的权限验证,可能有人会问为什么要先于子类运行。刚才我也说了,构造函数是用于

     初始化本类状态的,这也叫“先扫屋子再请客”的道理吧~,然后风雨兼程的回溯到Object的ctor中。

好了,如今来回答

     你的问题,先把这个问题简化一下。就不用web项目来演示了。

复制代码
 1     public class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var b = new Bird();
 6 
 7             Console.Read();
 8         }
 9     }
10 
11     public class Animal
12     {
13         public Animal()
14         {
15             Console.WriteLine("running first... i'm animal, all must be running after me.");
16         }
17     }
18 
19     public class Bird : Animal
20     {
21         public Bird()
22         {
23             Console.WriteLine("the next... i'm a cute bird.");
24         }
25     }
复制代码

能够看到,确实Animal于Bird先运行,可能有人会问,那Animal调用的是谁的ctor呢?当然就是Object了,我们能够看看IL:

 

Q: 既然你说构造函数用于初始化类的初始状态。那么请问下,我如今有一串这种

    json:{"Name":"smart","Age":2}。

实体类例如以下图,请问我的json序列化后,Age=?

复制代码
 1     [Serializable]
 2     public class Bird
 3     {
 4         private string name = "smart";
 5 
 6         public string Name
 7         {
 8             get { return name; }
 9             set { name = value; }
10         }
11 
12         private int age = 2;
13 
14         public int Age
15         {
16             get { return age; }
17             set { age = value; }
18         }
19 
20         public Bird()
21         {
22             Age = 5;
23         }
24     }
复制代码

 

A:事实上这个问题的关键在于,反序列化的时候是否会调用构造函数的问题,先来通过Reflector看下源代码,发现并没有代码,认为

    有点小奇怪,就用ILSpy反编译一下,相同也没有代码,不可否认。底层肯定是有代码运行的,要么反编译不出来。要么clr用了

    其它的方式,反正我们看不到实现源码,假设大家有什么好意见能够帮帮我,谢谢了

 

Reflector截图:

 

ILSpy截图:

据资料说。里面最后调用了FormatterServices里面的GetSafeUninitializedObject来分配对象内存。分配完后就不走构造器

了,所以针对这个问题,仅仅能记住了。最后为了验证一下,运行完代码之后确实没有走构造函数。

 

Q:我知道引用类型能够用构造器,那值类型为什么不能定义无參构造器?

A:这个问题问的好,编译器会依据性能考虑。不会调用值类型的构造函数,即使你强制的new一下也不会运行

复制代码
 1 namespace Sample
 2 {
 3     public class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Point point = new Point();
 8         }
 9     }
10 
11     public struct Point
12     {
13         public int Age;
14     }
15 }
复制代码

只是除非你自己显示定义有參构造函数。并且值类型有个特点就是读取之前必须初始化,否则会编译不通过。

 

Q:请问在类构造函数中能做单例吗?

A: 能不能做,就要看类构造器的特征了,我们知道类构造器跟实例构造器一样,他是用来初始化静态字段的,线程

     訪问类构造器的时候内部会进行加锁处理,所以多个线程同一时候訪问的时候,仅仅会有一个线程运行了类构造器。所以

     确实能够。

posted on 2017-05-12 19:09  ljbguanli  阅读(174)  评论(0编辑  收藏  举报