void show(string tag)
{
Console.WriteLine(tag);
}
void methodA()
{
throw new Exception("error msg");
show("A");
}
void methodB()
{
methodA();
show("B");
}
void methodC()
{
try
{
methodB();
show("C");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
這裡為了方便我們理解將程式展開成下面的樣子:
void show(string tag)
{
Console.WriteLine(tag);
}
void methodC()
{
try
{
methodB();
void methodB()
{
methodA();
void methodA()
{
throw new Exception("error msg");
//-----------------------------------------------------
show("A");
}
show("B");
}
show("C");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
從範例中我們可以看出兩個特性:
* 通透性
從 throw 的那一行開始 Exception 會一直向上傳遞,直到 catch 的區段。
* 脫離性
從 throw 的那一行之後的程式都不會被執行,會有類似 return 的效果,不同的是會對每一層的 method 都進行脫離,包含 try 的區段也會脫離。
methodC 的 catch 會捕獲從 methodA 丟出的 Exception,並且 Exception 中的 StackTrace 會紀錄 methodA, methodB, methodC,而 show() 都不會被執行。
由於大部分的程式邏輯都可以轉化成 else 就離開的程式流程,正好符合 throw 的脫離性,所以我們一開始在撰寫程式邏輯的時候,可以先專注在一般正常的流程邏輯上,之後再去補足檢查邏輯或脫離邏輯,最後在合適的位置進行 try catch 處理,或者在全域的錯誤處理中進行處理。
這裡有一個糟糕的 method,他用了個 Result 物件來裝載回傳結果以及錯誤訊息:
public class Result
{
public int Value { get; set; }
public string Error { get; set; }
}
public Result BadMethod(int input)
{
var result = new Result();
if (input > 0)
{
result.Value = 100 / input;
}
else
{
result.Error = "input 需要大於零";
}
return result;
}
如果用 Exception 可以讓程式簡單很多:
public int GoodMethod(int input)
{
if (input <= 0)
{
throw new Exception("input 需要大於零");
}
return 100 / input;
}
0 回應:
張貼留言