计算机视觉技术 editor Java Spring security cuda bootstrap侧边栏 spark数据清洗 matlab复数求模 matlab生成对角矩阵 matlab区分大小写吗 java解析pdf vue与html5 安装mysql python类和对象 python开发 python操作mysql python如何定义变量 javatrim stringjava java中的对象 java接口文档 java的for循环 java获取ip地址 java中map java如何编写接口 sql综合利用工具 js删除数组指定元素 js图片上传 html特殊符号 flash基础 思源字体 华为下拉开关设置 js分页 mac画图工具 js字符转数字 脚本学习 c程序 winhex中文版下载 dnf传说 mysql数据库恢复
当前位置: 首页 > 学习教程  > 编程学习

为什么值类型不允许显式定义无参构造函数

2021/1/9 2:17:51 文章标签: 无参构造函数

在看《CLR via C# 》这本书时,作者在谈到值类型的实例构造器时,说到值类型不能显式定义无参构造函数,那么问题来了,C#编译器为什么阻止这么做呢? 当程序以无参的形式new一个struct值类型时,分配一片内存&am…

  在看《CLR via C# 》这本书时,作者在谈到值类型的实例构造器时,说到值类型不能显式定义无参构造函数,那么问题来了,C#编译器为什么阻止这么做呢?

  当程序以无参的形式new一个struct值类型时,分配一片内存(注意该片内存是之前已经分配过的)并将这片内存的脏数据(因之前已经存储了一些数据)清除掉,即zeroed,这个工作是由CLR通过调用IL形式的initobj指令完成的。当用new操作符以无参形式构造一个struct时,new操作符被编译为initobj。

  事实上,CLR允许struct值类型显式定义无参构造器,但C#编译器不允许。考虑下面的例子:

  Struct[] foo = new Struct[1000];

  对于上面的语句,CLR能够通过分配内存并zeroed化内存的方式高效完成。如果我们显式定义一个无参构造函数,那么就意味着在执行上述语句时必须调用Struct的无参数构造函数1000次,这是极其低效率的。

  事实上,C#为了让struct和class的在实例构造这个行为上更加趋于一致,本可以允许struct值类型定义无参构造函数,但它必须保证该构造函数在类似上面的场景中不被反复调用从而导致低效率。个人认为显式定义的无参构造函数在一些场景被调用,而在另一些场景下不被调用,这破坏了一致性,同时令人困惑。因此,C#编译器干脆直接禁止显式定义无参构造函数

  在C#6.0的一个早期发行版本中,为了保持struct和class的一致性,微软确实放开了对struct值类型不能定义无参构造函数的限制,但是经过一段时间的测试和验证,发现这会导致一些奇怪的行为,因此,又重新恢复了之前的限制,即:不允许为struct值类型显式定义无参构造函数

  参考链接:

  1、https://github.com/dotnet/roslyn/issues/1029

  2、https://stackoverflow.com/questions/203695/does-using-new-on-a-struct-allocate-it-on-the-heap-or-stack#comment49327005_204009

转载于:https://www.cnblogs.com/lian--ying/p/9721671.html


本文链接: http://www.dtmao.cc/news_show_1100433.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?