C# 如何在类内部定义该类的编译时默认实例以减少冗余代码
实现方案
C# 要求方法默认参数必须为编译时常量,自定义引用类型的编译时常量仅支持null,因此直接将静态字段作为默认参数赋值无法直接通过编译,配合少量适配代码即可完整实现需求:
基础实现(适用于所有C#版本)
步骤1:定义不可变的全局默认实例
确保默认实例全局唯一、属性不可篡改,避免运行时被修改引发全局逻辑异常:
public class Foo<T> { // 设为只读属性,禁止外部修改实例属性 public T Prop1 { get; } public T Prop2 { get; } public Foo(T prop1, T prop2) { Prop1 = prop1; Prop2 = prop2; } // 静态只读字段,运行时全局唯一初始化,泛型类的每个封闭构造类型会生成独立的Empty实例 public static readonly Foo<T> Empty = new Foo<T>(default, default); }
注意:不要尝试用
const修饰Empty字段,C#不支持自定义引用类型的常量定义,会直接编译报错。
步骤2:适配默认参数逻辑
将方法的默认参数设为null,在方法入口处做 fallback 赋值即可:
// 方法定义 public void Bar<T>(T attri, Foo<T> inFoo = null) { // 无传参时自动使用默认实例 inFoo ??= Foo<T>.Empty; // 后续业务逻辑 }
优化实现(C# 7.2+可用)
如果Foo可以定义为只读值类型(readonly struct),则可以跳过null适配,直接使用默认参数:
public readonly struct Foo<T> { public T Prop1 { get; } public T Prop2 { get; } public Foo(T prop1, T prop2) { Prop1 = prop1; Prop2 = prop2; } public static readonly Foo<T> Empty = default; } // 方法可直接设置默认参数 public void Bar<T>(T attri, Foo<T> inFoo = default) { // 无传参时inFoo默认就是Empty实例,无需额外处理 }
内容的提问来源于stack exchange,提问作者Jim Gaf.
相关产品推荐
相关产品推荐

