如何解决C#中绑定事件时出现的Null Reference Exception?
解决SKCanvasView PaintSurface事件绑定的空引用异常问题
看起来你遇到的问题有两个关键根源,我们一步步来排查和解决:
1. 全局数组chart未初始化
从你的代码里可以看到,你在函数开头初始化了ChannelLabels和Plotlayouts数组,但没有对全局的chart数组做初始化操作。如果chart在之前没有被初始化过,它的初始值是null,当你尝试在循环中给chart[i]赋值时,就会直接抛出空引用异常。
解决方法:在循环开始前添加chart的初始化代码:
private void CreateUIElements() { int MAXCHANNELS = (int)App.UserPrefs[UserPreferenceReference.TotalChannels]; ChannelLabels = new Label[MAXCHANNELS]; Plotlayouts = new AbsoluteLayout[MAXCHANNELS]; // 新增这行,初始化chart数组 chart = new SKCanvasView[MAXCHANNELS]; for (int i = 0; i < MAXCHANNELS; i++) { // ... 后续代码保持不变 } }
2. 循环变量的闭包捕获陷阱
即使你初始化了chart数组,直接在lambda中捕获循环变量i也会导致隐藏问题:C#的lambda会捕获变量的引用,而不是当前循环迭代的具体值。这意味着所有绑定的事件处理程序都会共享同一个i变量,当循环结束后,i的值会变成MAXCHANNELS(超出数组的有效索引范围,数组最大索引为MAXCHANNELS-1)。当PaintSurface事件触发时,lambda里的i已经是这个超出范围的值,访问chart[i]就会引发空引用异常。
解决方法:在循环内部创建一个局部变量保存当前的索引值,让lambda捕获这个局部变量:
for (int i = 0; i < MAXCHANNELS; i++) { // ... 其他代码 chart[i] = new SKCanvasView { BackgroundColor = Color.White, VerticalOptions = LayoutOptions.FillAndExpand, HorizontalOptions = LayoutOptions.FillAndExpand, }; // 创建局部变量捕获当前i的具体值 int currentChannelIndex = i; chart[currentChannelIndex].PaintSurface += (sender, e) => OnCanvasViewPaintSurface(sender, e, currentChannelIndex); // ... 后续代码保持不变 }
先检查chart数组的初始化,再处理闭包的问题,就能解决这类循环中绑定事件的常见陷阱。
内容的提问来源于stack exchange,提问作者florent SERFAS
相关产品推荐
相关产品推荐

