为何结构体的成员不能在声明时赋值,而class的成员可以

为什么结构体的成员不能在声明时赋值,而class的成员可以?
我写了一个结构体的声明:

        struct m
        {
            int m_i = 0;
        }

结果,编译报错:
ConsoleApplication1.Program.m.m_i': cannot have instance field initializers in structs
-----------------------------------------------------------------------------------
C#这样设计的原因是什么? 为什么struct/class的初始化规则要不一样呢?
------解决方案--------------------
引用:
因为.NET不鼓励使用struct,所以没有糖吃

这绝对不是没有糖吃的问题,而是为了消除歧义。主要原因就是因为值类型没有默认的无参构造器,构造方式与引用类型是不同的。
------解决方案--------------------
值类型与引用类型的本质区别,仅仅是一个是直接寻址,一个是间接寻址。
与构造函数没有任何关系,这个条文不过是人为的规定而已,而不是因为技术实现上有什么问题。
------解决方案--------------------
C#本身就是为面向对象而生的,设计上把struct当成二等公民是很正常的,人家java都不支持struct。
------解决方案--------------------
引用:
C#本身就是为面向对象而生的,设计上把struct当成二等公民是很正常的,人家java都不支持struct。
另外有一点,值类型的继承也是很正常的需求,而且技术实现上比引用类型简单,然而C#却没有提供。
------解决方案--------------------
引用:
Quote: 引用:

首先明确一个事情,声明时赋值是什么时候做的事情。
这个赋值其实是在调用构造函数的时候生效的,本质是编译器将赋值语句内联到类型的每一个实例构造器的代码前面。

再然后继续讨论struct的问题,因为struct是值类型,不能为空。C#不允许为struct定义无参构造方法(但是CLR允许)。
任何一个struct类型的变量都会进行初始化,所有字段都会初始化成类型的初始值。
就拿你的例子来说,任何一个m类型的变量,m_i都会初始化成int的默认值,也就是0。这个初始化并不调用m类型的任何实例构造器,而是直接进行内存布局实现的。所以,这个过程中,声明赋值的代码根本不会被调用(因为没有调用构造方法)。
这就会导致歧义。
举个例子,假如你的m_i声明赋值为5,但是初始化之后m_i的实际值是0,这和你的预期明显不相符。所以C#也不允许为struct的字段进行声明赋值。


谢谢你的回答但是我有两点疑问:
(1)struct也可以有自己的构造器啊(无参的除外),和class一样,编译起将赋值语句“内联到类型的每一个实例构造器的代码前面”不就行了吗?
(2)换句话说,class如果不声明构造器,编译起默认也会初始化为类型的默认值吗?

值类型其实是没有无参的构造器的。初始化时直接对内存进行的操作,将成员赋值为类型的默认值。
因为没有无参构造器,也就没法内联。