C#中创建类构造函数的正确方式与优雅代码写法
C# 构造函数编写规范与优雅实现
是否存在标准写法?
C# 语言本身没有强制的构造函数编写语法规则,但.NET生态经过多年发展已经形成了社区普遍遵循的编码约定,遵循这些约定写出来的代码可读性、可维护性更强,也能和官方类库、第三方开源组件的代码风格保持统一。
核心约定如下:
- 构造函数访问修饰符要匹配类的使用场景:普通可实例化类用
public,抽象类构造函数用protected,不允许外部实例化的类(比如单例)用private,不要省略访问修饰符——C#类成员默认访问级别是private,漏写会导致外部无法调用构造函数创建实例 - 构造函数参数使用camelCase小驼峰命名,和PascalCase大驼峰的属性、公开字段做明确区分,不要给参数加下划线、匈牙利命名前缀
- 构造函数只做初始化赋值、必要的参数校验,不要在构造函数里写复杂业务逻辑、IO操作、网络请求这类重逻辑,构造函数执行应该是快速、无副作用的
- 类运行所必须的依赖、初始值必须通过构造函数传入,不要为了方便给必填属性的类留无参构造函数,避免对象创建完成后处于无效状态
- 存在多个构造函数时,通过
: this()语法串联构造函数,不要重复写赋值、校验逻辑 - 引用类型参数、值范围有要求的值类型参数,要在构造函数最开始做合法性校验,非法参数直接抛出明确的异常,避免后续业务逻辑执行时抛出无明确堆栈的异常
- 构造函数初始化后不需要修改的属性,不要无脑用
public set,根据场景用init(仅初始化时可赋值)或者readonly(构造函数内赋值),保障对象封装性
对你提供的参考代码的优化
你给出的代码可以正常运行,但存在几处不符合约定的问题:
- 类名
UsedCars是复数形式,.NET约定非集合类的类名使用单数名词,这里应该改为UsedCar - 两个属性都用了
public set,外部可以在对象创建后随意修改属性值,破坏了对象初始化后的状态稳定性 - 没有对参数做合法性校验:传入
model为null、wheels为0或负数时,会创建出逻辑上完全无效的二手车对象 - 类本身没有加访问修饰符,默认是
internal,如果需要在程序集外部访问会出问题
优化后的常规写法如下:
namespace Fahrzeuge { public class UsedCar { public int Wheels { get; init; } public string Model { get; init; } public UsedCar(int wheels, string model) { // 前置参数校验 if (wheels <= 0) throw new ArgumentOutOfRangeException(nameof(wheels), "车轮数量必须为正整数"); Model = model ?? throw new ArgumentNullException(nameof(model)); Wheels = wheels; } // 多构造函数串联,默认普通乘用车4个车轮 public UsedCar(string model) : this(4, model) { } } }
如果你使用C# 12及以上版本,可以用主构造函数语法进一步简化代码,逻辑完全一致:
namespace Fahrzeuge { public class UsedCar(int wheels, string model) { public int Wheels { get; init; } = wheels <= 0 ? throw new ArgumentOutOfRangeException(nameof(wheels), "车轮数量必须为正整数") : wheels; public string Model { get; init; } = model ?? throw new ArgumentNullException(nameof(model)); public UsedCar(string model) : this(4, model) { } } }
内容的提问来源于stack exchange,提问作者remidemi
相关产品推荐
相关产品推荐

