C#中结构和类的默认构造函数

本文探讨了C#中结构体和类在默认构造函数方面的差异。C#允许类在声明时对字段赋值初始化,而结构体则不允许,原因在于结构体的默认构造函数是隐式的,且不允许程序员自定义。C#的这种设计避免了二义性,并确保值类型的正确初始化。对于类,编译器会将初始化语句自动放到构造函数中,而结构体则需要显式赋值以符合编译要求。

不想看我废话直接看这个链接就行:

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/new-operator

研究这个的起因还是C#的类的字段可以赋值初始化,而在C++中是不行的(除了const static int(枚举)这种成员变量),原因是类声明时并未分配空间,而后查了一些资料才得知这是C#编译器将初始化语句自动放到了构造函数中,这就对上了,可为什么结构不行呢?为什么不对结构也进行这种优化,使得可以在写结构时对一些字段直接赋值初始化呢?

用代码实测,发现不仅不能直接对字段赋值,还不能自定义结构的默认构造函数(C++可以),自定义带参数的构造函数还必须对所有字段赋值,我去,说好比C++简单点的呢?为啥要求这么多?

其实说到底,就是这个默认构造函数一个问题了:请记住,为 struct 声明默认构造函数是错误的,因为每个值类型均隐式含有公共默认构造函数。这句话的重点就是公共这个词了,也就是说C#编译器在遇到类似这样的代码:

struct stu
{
    int age;
    string name;
}
int i = new int();
float i1 = new float();
stu xiaoming = new stu();

### C#默认构造函数的概念 当一个未显式定义任何构造函数时,C# 编译器会自动为此提供一个无参的默认构造函数[^1]。此默认构造函数不接受任何参数,并执行最基础的对象初始化工作。 对于值型,默认构造函数会在创建新实例时将其字段设置为其型的默认值。例如,在声明并使用 `new` 关键字初始化整数或浮点数值时,这些值会被设为0;而对于自定义结构体,则其所有字段也会被相应地初始化为它们各自型的默认值[^3]。 需要注意的是,一旦程序员在一个或者结构体内至少定义了一个带参数的构造函数之后,编译器就不会再生成默认构造函数了。此时如果仍然希望保留无参构造函数的话,就需要手动添加该构造函数[^4]。 ```csharp // 定义一个简单的 public class Person { private string _name; // 显式的无参构造函数 public Person() { _name = "Unknown"; } } // 使用默认构造函数创建对象 Person personInstance = new Person(); ``` ### 默认构造函数的具体作用 默认构造函数的主要目的是为了确保即使没有任何特定初始化逻辑的情况下也能成功创建对象实例。通过这种方式可以保证每一个新创建出来的对象都处于一种已知的状态之下,从而减少了潜在的安全隐患程序错误风险。 此外,对于某些框架组件或是依赖注入容器来说,拥有一个可访问的无参构造函数是非常重要的,因为这使得它们能够方便地实例化所需的而无需额外配置信息[^2]。 ### 结构体中的特殊情况 值得注意的是,在C#中为结构(struct)定义默认构造函数是不允许的,这是因为所有的值型都已经有一个隐含存在的公共无参构造函数来负责基本成员变量的初始化操作。 ```csharp struct Student { public int Age; public string Name; // 尝试定义默认构造函数将会引发编译错误 /* public Student() {} */ } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值