try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Di blok di atas kapan akhirnya blok dipanggil? Sebelum melempar e atau akhirnya dipanggil dan kemudian menangkap?
try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Di blok di atas kapan akhirnya blok dipanggil? Sebelum melempar e atau akhirnya dipanggil dan kemudian menangkap?
Jawaban:
Itu akan dipanggil setelah e dilemparkan kembali (yaitu setelah catch block dieksekusi)
mengedit ini 7 tahun kemudian - satu catatan penting adalah bahwa jika etidak ditangkap oleh blok coba / tangkap lebih jauh dari tumpukan panggilan atau ditangani oleh penangan pengecualian global, maka finallyblok tersebut mungkin tidak akan pernah dieksekusi sama sekali.
finallyTIDAK dijalankan jika pengecualian dilemparkan sebelumnya catchtidak pernah tertangkap dalam sebuah luar try- catchblock!
Mengapa tidak mencobanya:
outer try
inner try
inner catch
inner finally
outer catch
outer finally
dengan kode (diformat untuk ruang vertikal):
static void Main() {
try {
Console.WriteLine("outer try");
DoIt();
} catch {
Console.WriteLine("outer catch");
// swallow
} finally {
Console.WriteLine("outer finally");
}
}
static void DoIt() {
try {
Console.WriteLine("inner try");
int i = 0;
Console.WriteLine(12 / i); // oops
} catch (Exception e) {
Console.WriteLine("inner catch");
throw e; // or "throw", or "throw anything"
} finally {
Console.WriteLine("inner finally");
}
}
outer try inner try inner catch Unhandled Exception: System.DivideByZeroException...
Setelah membaca semua jawaban di sini, sepertinya jawaban akhirnya tergantung :
Jika Anda melemparkan kembali pengecualian di dalam blok tangkap, dan pengecualian itu ditangkap di dalam blok tangkap lain, semuanya dijalankan sesuai dengan dokumentasi.
Namun, jika pengecualian re-trown tidak ditangani, akhirnya tidak pernah dieksekusi.
Saya menguji contoh kode ini dalam VS2010 w / C # 4.0
static void Main()
{
Console.WriteLine("Example 1: re-throw inside of another try block:");
try
{
Console.WriteLine("--outer try");
try
{
Console.WriteLine("----inner try");
throw new Exception();
}
catch
{
Console.WriteLine("----inner catch");
throw;
}
finally
{
Console.WriteLine("----inner finally");
}
}
catch
{
Console.WriteLine("--outer catch");
// swallow
}
finally
{
Console.WriteLine("--outer finally");
}
Console.WriteLine("Huzzah!");
Console.WriteLine();
Console.WriteLine("Example 2: re-throw outside of another try block:");
try
{
Console.WriteLine("--try");
throw new Exception();
}
catch
{
Console.WriteLine("--catch");
throw;
}
finally
{
Console.WriteLine("--finally");
}
Console.ReadLine();
}
Berikut hasilnya:
Contoh 1: melempar kembali ke dalam blok try lain:
--outer try
---- inner try
---- inner catch
---- inner akhirnya
--outer catch
--outer akhirnya Huzzah
!Contoh 2: melemparkan kembali di luar blok percobaan lain:
-
coba --catchPengecualian Tidak Tertangani: System.Exception: Pengecualian jenis 'System.Exception' dilemparkan.
di ConsoleApplication1.Program.Main () dalam C: \ sumber lokal \ ConsoleApplication1 \ Program.cs: baris 53
Contoh Anda akan berperilaku identik dengan kode ini:
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
Sebagai catatan tambahan, jika Anda benar-benar bermaksud throw e;(yaitu, melemparkan pengecualian yang sama dengan yang baru Anda tangkap), itu jauh lebih baik untuk dilakukan throw;, karena itu akan mempertahankan jejak tumpukan asli daripada membuat yang baru.
finallyblok pada kenyataannya akan berjalan setelah catchblok (bahkan jika blok catch rethrows pengecualian), yang adalah apa potongan saya sedang mencoba untuk menggambarkan.
tryblok itu jawaban saya memiliki "coba-coba". Saya mencoba menjelaskan perilaku konstruksi 3 bagian dengan menggunakan dua konstruksi 2 bagian. Saya tidak melihat tanda-tanda tryblok kedua dalam pertanyaan awal, jadi saya tidak mengerti dari mana Anda mendapatkan itu.
Jika ada pengecualian yang tidak tertangani di dalam blok handler, blok akhirnya dipanggil tepat nol kali
static void Main(string[] args)
{
try
{
Console.WriteLine("in the try");
int d = 0;
int k = 0 / d;
}
catch (Exception e)
{
Console.WriteLine("in the catch");
throw;
}
finally
{
Console.WriteLine("In the finally");
}
}
Keluaran:
C: \ users \ administrator \ document \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
di coba
dalam tangkapan
Pengecualian Tidak Tertangani: System.DivideByZeroException: Mencoba untuk membagi dengan nol. di TestExceptionNesting.Program.Main (String [] args) di C: \ users \ administrator \ document \ TestExceptionNesting \ TestExceptionNesting.cs: line 22
C: \ users \ administrator \ document \ TestExceptionNesting \ bin \ release>
Saya mendapat pertanyaan ini hari ini di sebuah wawancara dan pewawancara terus kembali "apakah Anda yakin akhirnya tidak dipanggil?" Saya tidak yakin apakah itu berarti pertanyaan jebakan atau pewawancara memiliki sesuatu yang lain dalam pikiran saya dan menulis kode yang salah untuk saya debug sehingga saya pulang dan mencobanya (membangun dan menjalankan, tidak ada interaksi debugger), hanya untuk menempatkan pikiran saya pada beristirahat.
Menguji dengan Aplikasi Konsol C #, kode akhirnya telah dieksekusi setelah pengecualian dilemparkan: "Dialog Kesalahan Aplikasi" ada dan setelah Anda memilih opsi "Tutup program", blok akhirnya dieksekusi di jendela konsol itu. Tetapi pengaturan titik putus di dalam blok kode akhirnya, saya tidak pernah bisa memukulnya. Debugger terus berhenti pada pernyataan melempar. Ini kode pengujian saya:
class Program
{
static void Main(string[] args)
{
string msg;
Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
}
static int GetRandomNumber(out string errorMessage)
{
int result = 0;
try
{
errorMessage = "";
int test = 0;
result = 3/test;
return result;
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw ex;
}
finally
{
Console.WriteLine("finally block!");
}
}
}
Debugging di VS2010 - .NET Framework 4.0