亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在lambda表達式中使用foreach循環的迭代器變量-為什么失?。?/h1>

在lambda表達式中使用foreach循環的迭代器變量-為什么失?。?/h1>
C#
守候你守候我 2019-11-02 10:11:20
考慮以下代碼:public class MyClass{   public delegate string PrintHelloType(string greeting);    public void Execute()    {        Type[] types = new Type[] { typeof(string), typeof(float), typeof(int)};        List<PrintHelloType> helloMethods = new List<PrintHelloType>();        foreach (var type in types)        {            var sayHello =                 new PrintHelloType(greeting => SayGreetingToType(type, greeting));            helloMethods.Add(sayHello);        }        foreach (var helloMethod in helloMethods)        {            Console.WriteLine(helloMethod("Hi"));        }    }    public string SayGreetingToType(Type type, string greetingText)    {        return greetingText + " " + type.Name;    }...}調用之后myClass.Execute(),代碼將輸出以下意外響應:嗨Int32嗨Int32嗨Int32  很顯然,我希望"Hi String","Hi Single","Hi Int32",但顯然并非如此。為什么在所有3種方法中都使用了迭代數組的最后一個元素而不是適當的方法?您將如何重寫代碼以實現期望的目標?
查看完整描述

3 回答

?
縹緲止盈

TA貢獻2041條經驗 獲得超4個贊

歡迎來到閉包和捕獲變量的世界:)


埃里克·利珀特(Eric Lippert)對這種行為有深入的解釋:


關閉循環變量被認為是有害的

關閉循環變量,第二部分

基本上,捕獲的是循環變量,而不是值。要獲得您認為應該獲得的東西,請執行以下操作:


foreach (var type in types)

{

   var newType = type;

   var sayHello = 

            new PrintHelloType(greeting => SayGreetingToType(newType, greeting));

   helloMethods.Add(sayHello);

}


查看完整回答
反對 回復 2019-11-02
?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

作為暗示SWeko引用的博客文章的簡要說明,lambda捕獲變量而不是value。在foreach循環中,變量在每次迭代中都不是唯一的,在循環期間使用相同的變量(當您看到編譯器在編譯時對foreach執行的擴展時,這一點更加明顯)。結果,您在每次迭代中都捕獲了相同的變量,并且該變量(截至上次迭代)指的是集合中的最后一個元素。

更新:在較新版本的語言(從C#5開始)中,循環變量在每次迭代中都被視為新變量,因此關閉它不會產生與較早版本(C#4和更低版本)相同的問題。


查看完整回答
反對 回復 2019-11-02
?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

您可以通過引入其他變量來修復它:


...

foreach (var type in types)

        {

            var t = type;

            var sayHello = new PrintHelloType(greeting => SayGreetingToType(t, greeting));

            helloMethods.Add(sayHello);

        }

....


查看完整回答
反對 回復 2019-11-02
  • 3 回答
  • 0 關注
  • 743 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號