C# 包含参数的Lambda表达式。在VS2008中出现意外结果,在VS2013中效果良好
我不知道如何用语言准确地解释这个问题。我已经编写了代码来重现这个问题,并且我已经尽力使代码易于阅读C# 包含参数的Lambda表达式。在VS2008中出现意外结果,在VS2013中效果良好,c#,lambda,C#,Lambda,我不知道如何用语言准确地解释这个问题。我已经编写了代码来重现这个问题,并且我已经尽力使代码易于阅读 delegate string del(); static void Main(string[] args) { string[] ss = { "a", "b" }; Dictionary<string, del> dic = new Dictionary<string, delSS>(); foreach (string s in ss) {
delegate string del();
static void Main(string[] args)
{
string[] ss = { "a", "b" };
Dictionary<string, del> dic = new Dictionary<string, delSS>();
foreach (string s in ss) {
dic[s] = () => s;
}
foreach (string s in ss) {
System.Console.WriteLine("{0}:{1}", s, dic[s]());
}
System.Console.ReadLine();
}
这是VS2013的结果。
但在VS2008中,结果是
a:b
b:b
我在VS2013中尝试了从3.0到4.5的.Net Framework版本,以及所有版本
它们中的大多数给出了相同的结果。
我还在VS2008中尝试了3.0和3.5,它们也给出了相同的结果。我认为这意味着这不是框架的缺陷,而是编译器的缺陷。
我正在为WinCE 6.0开发一个应用程序,它只在VS2008和更早版本中受支持。这就是为什么我必须使用VS2008。我在调试WinCE应用程序时发现了这个问题。我认为这是Compact框架的一个缺陷,但事实证明这是VS2008的一个缺陷。
有人知道如何修复它吗?好吧,编译器变得更好了,我这样说;) 试一试
这将为每个
s
创建一个新的变量/值,以便闭包不会指向将由foreach
循环突变到最后的s
。在闭包中捕获循环变量是一件棘手的事情。VS2013为您整理了它,这很好,但我认为它根本不安全
Jon Skeet在这里(以及在他的书中)很好地解释了这一点:。代码质量工具(如Resharper)在您尝试执行此操作时会发出警告 这里有一个解决方案。
我做了以下修改,并在vs2008中试用过,效果非常好
委托字符串del(字符串sr)
static void Main()
{
字符串[]ss={“a”,“b”};
Dictionary dic=新字典();
foreach(ss中的字符串s)
{
dic[s]=(sr)=>sr;
}
foreach(ss中的字符串s)
{
System.Console.WriteLine(“{0}:{1}”,s,dic[s].Invoke(s));
}
System.Console.ReadLine();
}
a:b
b:b
foreach (string s in ss) {
var closed = s;
dic[s] = () => closed;
}
static void Main( )
{
string[] ss = { "a", "b" };
Dictionary<string, del> dic = new Dictionary<string, del >();
foreach (string s in ss)
{
dic[s] = (sr) => sr;
}
foreach (string s in ss)
{
System.Console.WriteLine("{0}:{1}", s, dic[s].Invoke(s));
}
System.Console.ReadLine();
}