我一直在开发一个 WPF 应用程序,并且偶然发现了一些有趣的东西,可能是因为我不知道它到底是如何工作的。
基本上我正在创建一个上下文菜单。该菜单有一个父 MenuItem,它有 3 个相同类型的子菜单项。这是最基本的代码。
public MainWindow()
{
InitializeComponent();
ContextMenu ctxMain = new ContextMenu();
MenuItem parent = CreateMenuItem("Parent", null);
for(int i = 0; i < 3; i++)
{
parent.Items.Add(CreateMenuItem(i.ToString(), () => MessageBox.Show(i.ToString())));
}
ctxMain.Items.Add(parent);
this.ContextMenu = ctxMain;
}
public MenuItem CreateMenuItem(string header, Action action)
{
MenuItem item = new MenuItem();
if (action != null)
{
item.Click += (object sender, RoutedEventArgs e) => action();
}
item.Header = header;
return item;
}
从视觉上看,它按预期工作。
但是我作为参数给出的操作表现得很奇怪。我希望每个子项的单击都能显示 MessageBox 中其标题中所写的内容。但它们都显示“3”。
我是否理解正确,我在 for 循环中定义的内联操作不会使用相同的参数“i”实例化三次,而只会实例化一次?或者它们是三个不同的 Action 实例,都引用同一个整数?我想听听对这里发生的事情的一些澄清。
提前致谢。 问候。
最佳答案
for(int i = 0; i < 3; i++)
{
var localCopy = i;
parent.Items.Add(CreateMenuItem(localCopy.ToString(), () => MessageBox.Show(localCopy.ToString())));
}
你的变量 i 被 lambda 表达式“捕获”。但在执行您的操作之前,i
已经发生了变化。并且您的操作在当前的 i
上执行,这意味着 3(循环之后以及您的操作最终执行时 i 的值)。
您需要制作变量的本地副本并使用它。由于它在循环内有自己的作用域,因此永远不会改变。
关于c# - 作用范围参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32070568/