struct QuaternionStruct
{float x;float y;float z;float w;
}

这是一个四元数的简单定义。

C# 目前的语法不允许为 struct 定义无参构造函数,凡是未显式调用带参版本的构造函数时,struct 对象初始化时总是简单的清零,这样就可以实现高效初始化(想象你有一个 struct 数组,如果每个 struct 元素需要调用构造函数,可能是非常大的开销)。但是,有时 struct 的零状态可能是没有意义的(比如上面的 Quaternion,通常我们会将 w 字段初始化为 1,代表默认旋转姿态),因为 C# 不允许为 struct 定义无参构造函数,我们不得不使用其他方式初始化这种 struct。

那么,如果允许为 struct 定义无参构造函数呢?

C# 中未显式初始化的成员字段会被初始化为默认值。对于引用类型成员字段,默认值是 null;对于值类型成员字段,默认值是零状态。其实两者本质上都是执行清零初始化,这在语法上是统一的。但是,如果需要显式初始化呢?

class QuaternionClass
{float x;float y;float z;float w;public QuaternionClass(){x = 0;y = 0;z = 0;w = 1;}
}class Program
{QuaternionStruct valueType = new QuaternionStruct();QuaternionClass referenceType = new QuaternionClass();
}

这里,Program 的值类型字段和引用类型字段都调用了无参构造函数执行初始化,但是结果却完全不同:因为引用类型的自定义无参构造函数将 w 初始化为 1,这样引用对象就不是零状态了;而值类型的初始化语法则令人困惑,因为值类型根本没有无参构造函数,仅仅是执行了清零初始化,这样一个已经初始化的值类型对象仍保持着没有意义的零状态!

也就是说,一个更统一、清晰、易用、易理解的语法,应当区别清零初始化与无参构造,将它们视为两种不同的过程。同时应当允许为 struct 定义无参构造函数。

这样可以带来哪些好处/变化?

首先是用于初始化的表达式语法可以统一了:

void DoSomething()
{// 这两条语句都是执行清零QuaternionStruct valueType1 = default;QuaternionClass referenceType1 = default;   // 或者 null// 这两条语句都可以将对象初始化为有效状态(非零状态)QuaternionStruct valueType2 = new QuaternionStruct();QuaternionClass referenceType2 = new QuaternionClass();// 这两条语句都创建了元素全是 default 值的数组var valueTypeArray = new QuaternionStruct[100];var referenceTypeArray = new QuaternionClass[100];
}

同时也意味着 struct 的成员字段应当允许使用“=”设置初始值了。

高效清零初始化仍然有效,还可以通过编译器优化将没有“实际价值”的自定义无参构造函数替换为高效清零。

还有就是如果定义了 struct 带参版本的构造函数而没有定义无参版本,理想设计应当是和 class 语法一致,即视为不存在无参构造函数;但考虑到兼容现有代码,凡是显式调用无参构造函数的代码暂处理为警告而非错误。

对于现有代码,因为之前没人写过 struct 的无参构造函数,所以凡是显式调用无参构造函数的代码与原语义是一致的。因此,允许为 struct 定义无参构造函数是向后兼容的。

(可能还有我没考虑到的地方,欢迎交流)

winowsformshost 的构造函数执行符合指定的绑定约束的_C# 应该允许为 struct 定义无参构造函数...相关推荐

  1. WPF 异常其他信息: “对类型“BaseControl.KImgButton”的构造函数执行符合指定的绑定约束的调用时引发了异常。”,行号为“38”,行位置为“22”。...

    引发的异常:"System.Windows.Markup.XamlParseException"(位于 PresentationFramework.dll 中)其他信息: &quo ...

  2. 对类型“H12.MainWindow”的构造函数执行符合指定的绑定约束的调用时引发了异常。

    对类型"H12.MainWindow"的构造函数执行符合指定的绑定约束的调用时引发了异常. 参考文章: (1)对类型"H12.MainWindow"的构造函数执 ...

  3. 解决VS2012 WPF中“对类型“ ”的构造函数执行符合制定的绑定约束的调用时引发了异常。行号为“3”,行位置为“9””问题的过程

    1.首先在网络上查找前人的经验,知道主程序构造函数中不能被调试.于是将全局变量初始化部分,从变量声明处放进了Load函数中. 2.运行后,变成"试图加载格式不正确的程序"或者&qu ...

  4. c++为什么一定要定义无参构造函数?类中无参构造的作用

    c++中无参构造函数的作用: 该类对象被创建时,编译系统为对象分配内存空间,并自动调用该构造函数->由构造函数完成成员的初始化工作. 故:构造函数的作用:初始化对象的数据成员. 举例: clas ...

  5. C++ 无参构造函数

    设计表示平面坐标位置的点类,可以修改和获取点的x.y坐标值,设置构造函数对点的数据成员进行初始化,并且能够用数组保存一系列的点. #include<iostream> using name ...

  6. c++的构造函数极其调用(无参构造函数,有参构造函数,拷贝构造函数)

    1.c++编译器会自动调用构造函数 //构造函数(与类名相同) //析构函数:没有参数也没有任何返回类型,被自动调用 #include<iostream> using namespace ...

  7. 为什么要写无参构造函数

    今天在码代码时报错: Cannot construct instance of org.tech.arthur.model.domain.DataTestDTO (no Creators, like ...

  8. .Net Framework 4.5.1 ASP.NET MVC 5 下新建视图报“错误 运行所选代码生成器时出错 无法检索元数据 没有为该对象定义无参数构造函数”...

    当在控制器中新建视图的时候,选择的视图界面如下: 执行添加后报如下错误: 错误的内容为: 错误 运行所选代码生成器时出错 无法检索"XXX"的元数据 没有为该对象定义无参数构造函数 ...

  9. 深入理解Kotlin无参构造函数

    Unsafe 创建实例 在java中 创建一个对象 其实主要就是3种方法 通过new 关键字来创建 这种是最常见的 通过反射构造方法来创建对象 这种也不少见.很多框架中都有使用. Unsafe类来创建 ...

最新文章

  1. T-SQL Convert转换时间类型
  2. 【Go】Go基础(三):基本结构和基本数据类型
  3. matlab 句柄图像尝试
  4. LVS(2)——针对于LVS的增删改方法
  5. 前端学习(1402):多人管理22验证joi
  6. Hibernate 查询数据
  7. 项目经理如何才能快速成长?
  8. 洛谷 P1036 [NOIP2002 普及组] 选数(DFS)
  9. 一款短小精悍的日志分析工具web_log_analyse
  10. 地温梯度 河南_河南省地热(温泉)分布规律
  11. 遗传算法-附代码注释
  12. python 函数 思维导图
  13. 最清晰的VGG16模型图
  14. python读取lmdb文件_python-将numpy数组写入lmdb
  15. 红外光电开关的原理与实验
  16. 独孤求败-武功高强深不可测的大侠~~
  17. obs摄像头模糊_【OBS虚拟摄像头插件】OBS虚拟摄像头下载OBS VirtualCam v2020 官方版-趣致软件园...
  18. 13个非常有用的Python代码片段
  19. 【B站】在电脑浏览B站视频时,暂停后自动播放的BUG
  20. 华为1+X认证网络系统管理与运维中级实验

热门文章

  1. JS制作没有Y轴的柱状图
  2. H5禁止手机自带键盘弹出
  3. SpringBoot项目启动时提示程序包不存在和找不到符号
  4. angular6继承类注意几点:
  5. Caffe RPN:把RPN网络layer添加到caffe基础结构中
  6. 旁瓣对消原理_雷达天线旁瓣对消技术
  7. Java微信公众平台开发(二)--微信服务器post消息体的接收
  8. Innodb中MySQL如何快速删除2T的大表
  9. vagrant 常用命令
  10. 邮件服务器之微软Exchange server (转)