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

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

概述  构造函数这玩意也是面试官经常会问到的东西,我们知道一个类的状态初始化就全靠它了,下面提几个小问题。Q:我看到Web项目里面通常都有一个BasePage页面,其中构造函数里面做了权限验证,     请问为什么要这么做。A:  既然这么做了,那么设计者肯定就知道了一个原则就是实例构造器中,父类构造器先于子类执行,那么这个先执行就可     以做很多有意思的事情,比如你说的权限验证,可能有人会问为什么要先于子类执行,刚才我也说了,构造函数是用于     初始化本类状态的,这也叫“先扫屋子再请客”的道理吧~,然后风雨兼程的回溯到Object的ctor中。好了,现在来回答     你的问题,先把这个问题简化一下,就不用web项目来演示了。1 public class Program2 {3 static void Main(string[] args)4 {5 var b = new Bird();67 Console.Read();8 }9 }1011 public class Animal12 {13 public Animal()14 {15 Console.WriteLine("running first... i'm animal, all must be running after me.");16 }17 }1819 public class Bird : Animal20 {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 Bird3 {4 private string name = "smart";56 public string Name7 {8 get { return name; }9 set { name = value; }10 }1112 private int age = 2;1314 public int Age15 {16 get { return age; }17 set { age = value; }18 }1920 public Bird()21 {22 Age = 5;23 }24 } A:其实这个问题的关键在于,反序列化的时候是否会调用构造函数的问题,先来通过Reflector看下源码,发现并没有代码,觉得    有点小奇怪,就用ILSpy反编译一下,同样也没有代码,不可否认,底层肯定是有代码执行的,要么反编译不出来,要么clr用了    其他的方式,反正我们看不到实现源代码,如果大家有什么好意见可以帮帮我,谢谢了 Reflector截图: ILSpy截图:据资料说,里面最后调用了FormatterServices里面的GetSafeUninitializedObject来分配对象内存,分配完后就不走构造器了,所以针对这个问题,只能记住了。最后为了验证一下,执行完代码之后确实没有走构造函数。 Q:我知道引用类型可以用构造器,那值类型为什么不能定义无参构造器?A:这个问题问的好,编译器会根据性能考虑,不会调用值类型的构造函数,即使你强制的new一下也不会执行1 namespace Sample2 {3 public class Program4 {5 static void Main(string[] args)6 {7 Point point = new Point();8 }9 }1011 public struct Point12 {13 public int Age;14 }15 }不过除非你自己显示定义有参构造函数,而且值类型有个特点就是读取之前必须初始化,否则会编译不通过。 Q:请问在类构造函数中能做单例吗?A: 能不能做,就要看类构造器的特征了,我们知道类构造器跟实例构造器一样,他是用来初始化静态字段的,线程     访问类构造器的时候内部会进行加锁处理,所以多个线程同时访问的时候,只会有一个线程执行了类构造器,所以     确实可以。 

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

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

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

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

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

Main( b = Console.Writeline( Console.Writeline( }

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

name = { { name = age = { { age = Age = }

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

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

    其他的方式,反正我们看不到实现源代码,如果大家有什么好意见可以帮帮我,谢谢了

Reflector截图:

ILSpy截图:

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

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

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

Main( Point point = }

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

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

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

     确实可以。

总结

以上是内存溢出为你收集整理的关于“构造函数”中的几个小问题,也许面试会问到哦~全部内容,希望文章能够帮你解决关于“构造函数”中的几个小问题,也许面试会问到哦~所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264081.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存