HOW TO:處理查詢運算式中的例外狀況 (C# 程式設計手冊)
可以在查詢運算式的內容中呼叫任何方法。 但是,建議您避免在會導致副作用的查詢運算式中呼叫任何方法,副作用包括修改資料來源的內容或擲回例外狀況。 此範例顯示如何避免在查詢運算式中呼叫方法時引發例外狀況,而不違反一般的 .NET Framework 例外狀況處理方針。 這些方針會說明當您了解為何會在指定內容中擲回特定例外狀況時,是可以攔截該例外狀況。 如需詳細資訊,請參閱例外處理。
最後的範例顯示在必須於查詢執行期間擲回例外狀況時,如何處理這些情況。
範例
下列範例顯示如何移動查詢運算式外的例外狀況處理程式碼。 這只有在方法不依賴查詢的任何區域變數時可行。
class ExceptionsOutsideQuery
{
static void Main()
{
// DO THIS with a datasource that might
// throw an exception. It is easier to deal with
// outside of the query expression.
IEnumerable<int> dataSource;
try
{
dataSource = GetData();
}
catch (InvalidOperationException)
{
// Handle (or don't handle) the exception
// in the way that is appropriate for your application.
Console.WriteLine("Invalid operation");
goto Exit;
}
// If we get here, it is safe to proceed.
var query = from i in dataSource
select i * i;
foreach (var i in query)
Console.WriteLine(i.ToString());
//Keep the console window open in debug mode
Exit:
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
// A data source that is very likely to throw an exception!
static IEnumerable<int> GetData()
{
throw new InvalidOperationException();
}
}
在某些情況下,對於從查詢內擲回之例外狀況最好的回應可能是立即停止執行查詢。 下列範例顯示如何處理從查詢主體內擲回的例外狀況。 假設 SomeMethodThatMightThrow 可能會造成需要停止執行查詢的例外狀況。
請注意,try 區塊包含 foreach 迴圈,但不包含查詢本身。 這是因為 foreach 迴圈是查詢實際執行的點。 如需詳細資訊,請參閱LINQ 查詢簡介 (C#)。
class QueryThatThrows
{
static void Main()
{
// Data source.
string[] files = { "fileA.txt", "fileB.txt", "fileC.txt" };
// Demonstration query that throws.
var exceptionDemoQuery =
from file in files
let n = SomeMethodThatMightThrow(file)
select n;
// Runtime exceptions are thrown when query is executed.
// Therefore they must be handled in the foreach loop.
try
{
foreach (var item in exceptionDemoQuery)
{
Console.WriteLine("Processing {0}", item);
}
}
// Catch whatever exception you expect to raise
// and/or do any necessary cleanup in a finally block
catch (InvalidOperationException e)
{
Console.WriteLine(e.Message);
}
//Keep the console window open in debug mode
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
// Not very useful as a general purpose method.
static string SomeMethodThatMightThrow(string s)
{
if (s[4] == 'C')
throw new InvalidOperationException();
return @"C:\newFolder\" + s;
}
}
/* Output:
Processing C:\newFolder\fileA.txt
Processing C:\newFolder\fileB.txt
Operation is not valid due to the current state of the object.
*/
編譯程式碼
建立以 .NET Framework 3.5 版為目標的 Visual Studio 專案。 根據預設,專案有 System.Core.dll 的參考,以及 System.Linq 命名空間的 using 指示詞。
將程式碼複製至您的專案中。
按 F5 編譯和執行程式。
按任何鍵離開主控台視窗。