C#与Arduino串口通信时foreach循环报错CS0103的解决及代码重构
错误原因
你触发CS0103报错的核心原因有两个:
- 变量
tb的作用域仅存在于SelectMany(tb => myCommands)的Lambda表达式内部,Lambda外部的foreach循环无法访问该变量 - 你的
SelectMany用法不符合业务逻辑:该写法会让每个TextBox对应全部8条指令,最终会循环执行64次读写操作,完全不是你预期的「一条指令对应一个TextBox」的匹配逻辑
修复方案
方案1:使用for循环(推荐初学者使用,逻辑直观易调试)
直接通过索引同时匹配指令数组和文本框数组,一一对应执行读写:
private void button3_Click(object sender, EventArgs e) { TextBox[] myTextBoxes = new TextBox[] { textBox9, textBox10, textBox11, textBox12, textBox13, textBox14, textBox15, textBox16 }; String[] myCommands = new String[] { "#TRMMH1\n", "#TRMMM1\n", "#TRMMH2\n", "#TRMMM2\n", "#TRMMH3\n", "#TRMMM3\n", "#TRMMH4\n", "#TRMMM4\n" }; String inString; // 两个数组长度一致,直接用索引遍历 for (int i = 0; i < myCommands.Length; i++) { port.Write(myCommands[i]); inString = port.ReadLine(); myTextBoxes[i].Text = inString; } }
方案2:使用Zip方法配对数组(LINQ写法)
如果要使用LINQ风格的写法,可以用Zip方法把两个数组按位置配对成元组遍历:
private void button3_Click(object sender, EventArgs e) { TextBox[] myTextBoxes = new TextBox[] { textBox9, textBox10, textBox11, textBox12, textBox13, textBox14, textBox15, textBox16 }; String[] myCommands = new String[] { "#TRMMH1\n", "#TRMMM1\n", "#TRMMH2\n", "#TRMMM2\n", "#TRMMH3\n", "#TRMMM3\n", "#TRMMH4\n", "#TRMMM4\n" }; String inString; foreach (var item in myTextBoxes.Zip(myCommands, (tb, cmd) => new { TextBox = tb, Command = cmd })) { port.Write(item.Command); inString = port.ReadLine(); item.TextBox.Text = inString; } }
额外注意:串口操作
ReadLine默认是阻塞调用,建议提前给port对象设置ReadTimeout属性(比如设为1000毫秒),避免Arduino无返回时程序直接卡死。
内容的提问来源于stack exchange,提问作者OndiAluc
相关产品推荐
相关产品推荐

