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

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

C#在預見中重用變量有什么原因嗎?

C#在預見中重用變量有什么原因嗎?

慕桂英3389331 2019-06-09 15:42:14
C#在預見中重用變量有什么原因嗎?在C#中使用lambda表達式或匿名方法時,我們必須警惕訪問修改后的閉包陷阱。例如:foreach (var s in strings){    query = query.Where(i => i.Prop == s); // access to modified closure    ...}由于修改了閉包,上述代碼將導致所有Where的最后一個值為基礎的查詢中的子句。s.如所解釋這里,這是因為s中聲明的變量foreach上面的循環在編譯器中是這樣翻譯的:string s;while (enumerator.MoveNext()){    s = enumerator.Current;    ...}而不是這樣:while (enumerator.MoveNext()){    string s;    s = enumerator.Current;    ...}如前所述這里,在循環之外聲明變量沒有任何性能優勢,在正常情況下,我能想到這樣做的唯一原因是如果您計劃在循環范圍之外使用該變量:string s;while (enumerator.MoveNext()){    s = enumerator.Current;    ...}var finalString = s;中定義的變量。foreach循環不能在循環之外使用:foreach(string s in strings){}var finalString = s; // won't work: you're outside the scope.因此,編譯器聲明變量的方式使它非常容易出錯,而錯誤通常很難找到和調試,同時也不會產生任何可感知的好處。你有什么可以用的嗎?foreach循環是這樣的,如果它們是用內部作用域變量編譯的,或者這只是在匿名方法和lambda表達式可用或通用之前所做的任意選擇,而且從那時起就沒有修改過?
查看完整描述

3 回答

?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

你要問的是埃里克·利珀特在他的博客文章中詳細介紹了他的問題。關閉被認為有害的循環變量還有它的續集。

對我來說,最有說服力的論點是,在每次迭代中使用新變量將不符合for(;;)樣式循環。你想要一個新的int i在每一次迭代中for (int i = 0; i < 10; i++)?

這種行為最常見的問題是對迭代變量進行閉包,并且有一個簡單的解決方法:

foreach (var s in strings){
    var s_for_closure = s;
    query = query.Where(i => i.Prop == s_for_closure); // access to modified closure

我在博客上發表了關于這個問題的文章:C#中Foreach變量的閉包.


查看完整回答
反對 回復 2019-06-09
?
躍然一笑

TA貢獻1826條經驗 獲得超6個贊

被這樣咬過之后,我習慣于將本地定義的變量包含在最內部的范圍中,用于轉移到任何閉包。在你的例子中:

foreach (var s in strings){
    query = query.Where(i => i.Prop == s); // access to modified closure

我知道:

foreach (var s in strings){
    string search = s;
    query = query.Where(i => i.Prop == search); // New definition ensures unique per iteration.

一旦你有了這個習慣,你就可以在非常罕見的情況,您實際上打算綁定到外部作用域。老實說,我從來沒有這樣做過。


查看完整回答
反對 回復 2019-06-09
  • 3 回答
  • 0 關注
  • 415 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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