C#自定义forEach(Action)方法调用lambda赋值后数组元素全为null
错误原因
问题出在C#的参数传递规则,和Action委托本身的使用逻辑无关:
- 用
new Neuron[AmountOfNeurons]初始化引用类型数组时,所有元素的默认值都是null - 你传入
forEach的lambda表达式x => x = new Neuron(AmountOfNeurons)中,x是方法传入的参数本地副本,对这个副本赋值只会修改副本本身的引用,完全不会改动原数组里存储的元素值,循环执行完数组元素自然全是初始的null - 你当前实现的
forEach仅支持对数组中已经存在的实例做操作,无法实现给数组元素重新赋值的效果。
修复方法
方案1:初始化场景直接用普通循环(推荐)
你的forEach本身逻辑没有错误,只是适用场景是遍历操作已有元素,不适合做数组初始化赋值,初始化直接写基础循环即可:
public void CreateNeurons(int AmountOfNeurons) { this.Neurons = new Neuron[AmountOfNeurons]; for(int i = 0; i < this.Neurons.Length; i++) { this.Neurons[i] = new Neuron(AmountOfNeurons); } }
原有forEach可以继续用在遍历操作场景,比如调用所有神经元的方法、修改神经元属性这类不替换元素本身的操作:
// 示例:遍历所有神经元执行初始化权重操作 this.forEach(x => x.InitRandomWeights());
方案2:改造forEach支持修改原数组元素
如果一定要通过传入的lambda完成数组元素赋值,需要将参数改为按引用传递,由于内置Action不支持ref参数,需要先自定义委托类型:
// 定义支持按引用传参的委托 public delegate void RefAction<T>(ref T item); public void forEach(RefAction<Neuron> action) { for(int i = 0; i < this.Neurons.Length; i++) { action(ref this.Neurons[i]); } } public void CreateNeurons(int AmountOfNeurons) { this.Neurons = new Neuron[AmountOfNeurons]; // 此时对x赋值会直接修改原数组对应位置的元素 this.forEach((ref Neuron x) => x = new Neuron(AmountOfNeurons)); }

内容的提问来源于stack exchange,提问作者LetsHenne
相关产品推荐
相关产品推荐

