C#无参数类初始化时,如何从init属性填充readonly字段?
解决方案
方法1:使用Lazy延迟初始化数组
通过Lazy<T>将数组的生成延迟到第一次访问时,确保对象初始化器设置的ElementCount值被正确读取:
public class ArrayBenchmark { private readonly Lazy<int[]> _numbers; public uint ElementCount { get; init; } = 1; public ArrayBenchmark() { _numbers = new Lazy<int[]>(() => Enumerable.Range(0, (int)ElementCount) .Select(_ => new Random().Next(-9, 10)) .ToArray()); } // 对外提供只读的数组访问入口 public IReadOnlyList<int> Numbers => _numbers.Value; public void CalculateAllComplexities() { // 使用Numbers进行业务逻辑处理 foreach (var number in Numbers) { // ... } } }
优势:
- 保留
_numbers的readonly特性,确保数组生成后无法被修改 - 数组仅在第一次被访问时生成,避免不必要的资源消耗
- 完全兼容对象初始化器的使用方式,代码逻辑清晰
方法2:在ElementCount的init setter中初始化数组
如果可以接受_numbers不标记为readonly,直接在ElementCount的初始化器中生成数组:
public class ArrayBenchmark { private int[] _numbers = Array.Empty<int>(); private uint _elementCount = 1; public uint ElementCount { get => _elementCount; init { _elementCount = value; // 直接根据设置的值生成数组 _numbers = Enumerable.Range(0, (int)value) .Select(_ => new Random().Next(-9, 10)) .ToArray(); } } public IReadOnlyList<int> Numbers => _numbers; public void CalculateAllComplexities() { // 业务逻辑处理 } }
注意:这种方式下_numbers无法标记为readonly,但能直接满足对象初始化器的使用需求。
内容的提问来源于stack exchange,提问作者Daniel Hanák
相关产品推荐
相关产品推荐

