沒有,有沒有辦法直接做到這一點。關於如何做這種事情,有幾種不同的思想流派。比較和對比這兩個:
originalState = GetState();
SetState(newState);
DoSomething();
SetState(originalState);
VS
originalState = GetState();
SetState(newState);
try
{
DoSomething();
}
finally
{
SetState(originalState);
}
很多人會告訴你,後者則是 「更安全」。
這不一定如此。
兩者之間的差異當然是即使DoSomething()拋出異常,後者也會恢復狀態。那是更好比在異常情況下保持狀態變異? 是什麼讓它更好?你有一個意外的,未處理的異常報告,可怕的和意外的已經發生。你的內部狀態可能會完全不一致和任意混亂;沒有人知道在例外情況下可能發生了什麼。我們所知道的是,DoSomething可能正試圖對變異狀態做些事情。
在發生可怕和未知事件的情況下,是否真的是正確的做法,不斷攪動那個特定的罐子,並嘗試改變剛剛導致異常的狀態再次?
有時這將是做正確的事,有時它會更糟。你實際使用哪種場景取決於代碼的完成情況,因此仔細考慮在盲目選擇其中一個之前做正確的事情。
坦率地說,我寧願沒有取得進入擺在首位的情況下解決問題。我們現有的編譯器設計使用了這種設計模式,坦率地說,它是令人生氣的。在現有的C#編譯器中,錯誤報告機制是「副作用」。也就是說,當編譯器的一部分出現錯誤時,它會調用錯誤報告機制,然後將錯誤顯示給用戶。
這是拉姆達結合的一個主要問題。如果您有:
void M(Func<int, int> f) {}
void M(Func<string, int> f) {}
...
M(x=>x.Length);
那麼這個工作的方式是,我們嘗試綁定
M((int x)=>{return x.Length;});
和
M((string x)=>{return x.Length;});
,我們看看哪一個,如果有的話,給了我們一個錯誤。在這種情況下,前者給出錯誤,後者編譯時沒有錯誤,所以這是合法的lambda轉換,重載解析成功。 我們如何處理錯誤?我們無法向用戶報告,因爲此程序無錯誤!
我們做什麼。因此,當我們綁定一個lambda的身體是你說什麼:我們告訴了記者的錯誤「不報你的錯誤,給用戶;他們在這個緩衝區保存在這裏,而不是」。然後我們綁定lambda,將錯誤記錄器恢復到它以前的狀態,並查看錯誤緩衝區的內容。
我們可以完全避免這個問題,通過改變表達分析儀,使其與結果一起返回的錯誤,而不是讓錯誤的狀態有關的副作用。然後,對錯誤報告狀態進行變更的需求完全消失,我們甚至不必擔心。
所以我會鼓勵你重新審視你的設計。有沒有一種方法可以使您正在執行的操作不依賴於您正在變異的狀態?如果是這樣,那麼就這樣做,然後你不必擔心如何恢復變異狀態。 (當然在我們的例子中,我們的做想要在異常時恢復狀態如果在lambda綁定過程中編譯器內部的某個東西會拋出,我們希望能夠向用戶報告這一點!我們不需要希望錯誤記者留在「壓制報告錯誤」狀態。)
軟件事務內存? – shahkalpesh
傷心地看到你有一個非常好的代表,並且仍然將整個問題作爲標題發佈。 – Shoban
你能詳細說明你需要什麼這個構造?發生這種情況時,會自動通過值傳遞變量,例如進行函數調用時,但我不確定這是您正在尋找的。 – GrayWizardx