這只是一個「我很好奇」的問題。C# - 如何創建一個不可檢測的無限循環?
在C#-in深入喬恩斯基特說,大約lambda表達式:
「如果有一個非空返回類型每個代碼路徑必須返回一個值兼容」(頁233)
的腳註接着說:
「的代碼路徑拋出異常並不需要返回過程中的價值,也不做檢測的無限循環。」(第233頁)
我想知道什麼構成了無法察覺的無限循環?
這隻能通過邏輯來完成嗎?還是通過使用外部因素(如數據庫或文件系統)來完成?
這只是一個「我很好奇」的問題。C# - 如何創建一個不可檢測的無限循環?
在C#-in深入喬恩斯基特說,大約lambda表達式:
「如果有一個非空返回類型每個代碼路徑必須返回一個值兼容」(頁233)
的腳註接着說:
「的代碼路徑拋出異常並不需要返回過程中的價值,也不做檢測的無限循環。」(第233頁)
我想知道什麼構成了無法察覺的無限循環?
這隻能通過邏輯來完成嗎?還是通過使用外部因素(如數據庫或文件系統)來完成?
什麼喬恩指的是在本說明書中的第8.1節中描述。編譯器只能檢測到非常簡單的無限循環,如:
while(true) { if (0 != 0) return 123; }
編譯器是足夠聰明地看到,回報率從未達到的,因此該循環將永遠運行下去。它是合法的,但瘋了,說:
int M() { while(true) { } }
,因爲雖然沒有路徑返回一個int,也沒有路徑返回沒有返回一個int!
編譯器不夠聰明,找不到其他種類的無限循環。例如:
int x = 123;
while(true) { if (x * 0 != 0) break; }
這顯然是一個無限循環。但編譯器不知道這一點。編譯器說:「好吧,也許有一些x的值,其中x * 0不是零,因此中斷可以到達,所以這不是一個無限循環。你和我知道這是不可能的,因爲我們知道數學,但編譯器沒有。
如果您想了解詳情,請閱讀第8.1節。
我其實不記得寫這個 - 這表明腳註是由於你的影響:) – 2010-02-22 23:04:55
@Jon:你最初寫道「拋出異常的代碼路徑不需要返回值,當然」。我注意到可檢測的無限循環也被視爲無法達到的終點。 – 2010-02-22 23:36:06
對 - 這似乎是我們每個人都想出來的更可能的細節水平:) – 2010-02-23 00:09:26
使用外部資源創建無限循環,甚至濫用接口等工具都非常簡單。
例如:
public interface INumbers
{
int GetNumber(int arg);
}
public class StaticNumber : INumbers
{
public int GetNumber(int arg)
{
return 1;
}
}
public void DoStuff(INumbers num)
{
int i = 42;
while ((i = num.GetNumber(i)) != 0)
{
;
}
}
然後簡單
Action action =() => DoStuff(new StaticNumber());
@JonSkeet也許他可以澄清。 – 2010-02-22 18:50:29