C#中是否有简洁语法可在属性为null时实例化并指定构造参数?
问题
在C#中访问可空类型属性时,希望实现:若属性当前值为null,自动调用带指定参数的主构造函数实例化新值并返回;若属性非null则直接使用现有值,且理想情况下属性非null时构造参数不会被求值。
当前必须先判断再赋值,代码示例如下:
if (o.some_property == null) o.some_property = new SomeType(); o.some_property.some_field = 7;
期望更简洁的语法形式,例如:
o.some_property!().some_field = 7; o.some_property!("Sam", 7).some_field = 7;
询问C#是否原生支持此类特性。
回答
C#目前没有原生支持你期望的这种直接调用构造函数的简洁语法,但可以通过两种方式实现类似效果,且满足"非null时构造参数不被求值"的要求:
1. 空合并赋值运算符(无参数构造场景)
如果是无参数构造的情况,用??=运算符可以直接简化判断赋值逻辑,和原代码逻辑完全等价,且只有属性为null时才会执行构造:
o.some_property ??= new SomeType(); o.some_property.some_field = 7;
2. 自定义泛型扩展方法(支持带参数构造)
如果需要支持带参数的构造,且保证非null时构造参数不被求值,可以编写泛型扩展方法,用Func<T>延迟构造逻辑的执行:
public static class NullableExtensions { public static T EnsureInitialized<T>(this ref T? property, Func<T> factory) where T : class { if (property == null) { property = factory(); } return property; } }
使用时通过lambda传入构造逻辑,只有属性为null时,lambda内的构造代码才会被执行:
// 无参数构造场景 o.EnsureInitialized(ref o.some_property, () => new SomeType()).some_field = 7; // 带参数构造场景 o.EnsureInitialized(ref o.some_property, () => new SomeType("Sam", 7)).some_field = 7;
这种方式既保证了简洁性,也完全满足自动初始化、非null时构造参数不被求值的需求。
内容的提问来源于stack exchange,提问作者Matt Cruikshank
相关产品推荐
相关产品推荐

