[英]newbie C# - How to make a goto statement inside a while loop?
我怎樣才能使這個IL_ABC goto語句進入while循環呢? 如果不可能的話,我能否解釋一下為什么禁止它,以及對性能相同的修改提出建議? 非常感謝!!!
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace test.Properties
{
internal class Testing
{
public Testing()
{
Data.smethod_0();
}
[DllImport("myfile.dll")]
public static extern bool EM(int int0, string string0);
public static void smethod_0(object object0)
{
try
{
while (true)
{
IL_ABC:
Process[] processesByName = Process.GetProcessesByName("dummy");
if (processesByName.Length == 1)
{
if (Testing.EM(processesByName[0].Id, "a.dll"))
{
processesByName[0].Kill();
Thread.Sleep(2000);
continue;
}
Thread.Sleep(2000);
if (Testing.EM(processesByName[0].Id, "b.dll"))
{
processesByName[0].Kill();
Thread.Sleep(2000);
continue;
}
}
Thread.Sleep(2000);
}
}
catch (Exception ex)
{
Debug.smethod_0("Error! " + ex.Message);
Thread.Sleep(2000);
goto IL_ABC;
}
}
}
}
“如果不可能的話,我可以解釋為什么它被禁止嗎”
忽略代碼的問題(其他現有的答案解決),我將嘗試提供原因的解釋。 這是C#語言規范的引文
如果當前函數成員中不存在具有給定名稱的標簽,或者goto語句不在標簽范圍內,則會發生編譯時錯誤。 該規則允許使用goto語句將控制權移出嵌套范圍,但不能移入嵌套范圍。
在執行到您的GOTO語句時,您的標簽已經超出范圍,並且不再有效。 您可以通過在while循環中聲明一個整數並嘗試在catch塊中對其進行訪問來進行測試。
不要使用goto
相反,您可以這樣編寫代碼:
while (true)
{
try
{
Process[] processesByName = Process.GetProcessesByName("dummy");
if (processesByName.Length == 1)
{
if (Testing.EM(processesByName[0].Id, "a.dll"))
{
processesByName[0].Kill();
Thread.Sleep(2000);
continue;
}
Thread.Sleep(2000);
if (Testing.EM(processesByName[0].Id, "b.dll"))
{
processesByName[0].Kill();
Thread.Sleep(2000);
continue;
}
}
Thread.Sleep(2000);
}
catch (Exception ex)
{
Debug.smethod_0("Error! " + ex.Message);
Thread.Sleep(2000);
}
}
在內部塊范圍內直接使用GOTO對開發人員來說很方便,但這對編譯器編寫者來說是一個很大的麻煩。 問題在於,在進入任何塊的范圍時,您的程序都應該在后台做某些事情。 就像在進入try-catch塊時一樣,它應該在堆棧上創建一個特殊的框架,在進入常規塊時,它應該分配所有作用域局部變量,在進入for循環體時,它應該執行其初始化程序,依此類推。 如果您只是在嵌套塊內的某個隨機點處跳轉,那么所有這些內容都將被繞過,並且程序將簡單地崩潰。 從理論上講,編譯器可以在處理GOTO跳轉時針對所有可能的情況解決並提交這些內容,但是實際上,在C#編譯器中創建此類功能所花費的工作量不值得您擁有它。 因此,在C#中僅禁用了進入嵌套內部范圍的GOTO,並且所有塊都必須具有單個入口點,這是該塊的左開口括號。 在您的特定情況下,您只需要將IL_ASM標簽移動到try-catch塊之外(就在'try'關鍵字之前),它將起作用,但更合適的方法是使用以下構造:
bool repeat = true;
while (repeat)
{
try
{
... do something...
repeat = false;
}
catch
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.