เราเดินทางมาถึงบทสำคัญแล้วครับ ณ จุดนี้คุณคงเขียนโปรแกรมอย่างง่ายได้แล้ว งานที่ทุกอย่างเสร็จใน Function เดียวคุณคงทำได้อย่างสบาย ถ้าคุณติดตามมาตั้งแต่ต้น มาบทนี้เป็นบทสำคัญครับ เป็นบทที่ว่าด้วยเรื่อง การทำให้โปรแกรมไม่โดน TKO โดย .Net ถึงจะลุกไม่ไหวจริงๆ ก็ให้มันมีสติพอที่จดจำเหตุการณ์ว่าโดนหมัดแบบไหนถึงจอด ใช่ครับผมกำลังพูดถึงว่าเมื่อโปรแกรมคุณพบข้อผิดพลาด ในชีวิตจริง เช่นคุณเขียนโปรแกรม หารเลข โปรแกรมของคุณทำงานได้ถูกต้องเสมอมา จนกระทั่งใครไม่รู้เพี้ยนใส่ 0 เป็นตัวหาร การหารด้วย 0 ไม่นิยามครับ ดูตัวอย่างนี้ครับ.Net TKO คุณทันที โดยการแสดง popup หน้าจอที่พอจำใจความว่า ทนไม่ไหวแล้วตายดีกว่า และมีคุณกด OK มัน

int num = 0;
int
x = 1 / num;
Console.WriteLine("Done");

เมื่อคุณ Run โปรแกรม .Net TKO คุณทันที โดยการแสดง popup หน้าจอที่พอจำใจความว่า ทนไม่ไหวแล้วตายดีกว่า และมีคุณกด OK มันจะแสดง error ว่า

Exception occurred: System.DivideByZeroException: Attempted to divide by Zero.
at exp.Main() in c:\cs\exp1.cs:line 8

คำว่า Done ไม่ได้แสดงเพราะโปรแกรมโดน TKO ก่อน เมื่อมีการหารด้วย 0 มันจึงสร้าง error ที่ชื่อว่า DivideByZeroException

 ถึงแม้ว่าคุณบอกว่าเรื่องนี้มันขึ้นอยู่กับการเขียนโปรแกรม ถ้าก่อนการคำนวณ การหาร คุณตรวจสอบว่าตัวหารเป็น 0 หรือไม่ มันก็จะไม่ถูก TKO มันก็จริงครับ แต่คุณจะเหนื่อยขึ้นมากถ้าต้องตรวจสอบทุดจุด ถึงกระนั้นก็ไม่ได้หมายความว่าคุณจะไม่โดน TKO ยังมีอีกหลายจุดครับโดยเฉพาะเรื่องของ I/O คุณเขียน code ดักไม่ได้หรอกครับ เช่นถ้าคุณเขียน data ลงบน floppy disk แต่ผู้ใช้ลืมใส่แผ่น Disk แบบนี้ยังไงก็โดย TKO ครับ
    ในเมื่อคุณไม่สามารถป้องกันการเกิด Error ได้ทุกจุด แต่ C# เตรียมวิธีทางออกให้ครับ โดยที่ให้มันเกิดปัญหาก่อนแล้วมาดักไม่ให้โปรแกรมโดน TKO ในตัวอย่างข้างบน ก็ปล่อยมันครับ ใครจะหารด้วย 0 ก็คามใช้ไม่ต้องป้องกัน แต่เมื่อเกิด error ขึ้นแล้วคุณสามารถเขียน code เพื่อบอกให้ทำอะไร ก็ได้ที่คุณต้องการทำ เช่นกลับไปพยายามต่อ หรือช่างมัน code ไม่สำคัญ ปล่อยไปเลยเป็นต้น
เรามาดูตัวอย่างการทำ exception handling กัน

exception.cs

using System;

class
exception
{
  
public static void Main()
   {
      int num = 0;

      try {
         int x = 1 / num;
      }

      catch(DivideByZeroException e) {
         Console.WriteLine("DivideByZero Exception : {0} ", e.Message);
      }

      Console.WriteLine("Done");
  
}
}

DOS Prompt

C:\CS>exception
DivideByZero Exception: Attempted to divide by zero.
Done

C:\cs>_

  เรามาแยกชิ้นส่วนดูกันเลย

try {
   int x = 1 / num;
}

 จะเห็นจาก code นี้ว่า บรรทัดไหนที่มีโอกาสเกิด error ได้ เราก็เอา try { } ไปคร่อมไว้ ในกรณีนี้มี error เกิดขึ้น เพราะคุณหารด้วย 0  จึงเกิด error ที่เกิดขึ้นชื่อว่า DivideByZeroException

 

catch(DivideByZeroException e) {
   Console.WriteLine("DivideByZero Exception : {0} ", e.Message);
}

เมื่อ try { } มี error เกิดขึ้น จะมาที่บรรทัด catch นี้ แต่ถ้าไม่เกิด error ใน try { } มันจะข้าม catch ไปเลย ในกรณีนี้มี error เกิดขึ้น มันจะเข้ามาทำที่ catch ซึ่ง parameter ของ catch จะเป็นตัวกำหนดชนิดของ error ที่ต้องการดัก ถ้าไม่ตรง ก็จะข้ามไปไม่ run โปรแกรมใน block แต่ในที่นี้ เกิด error ที่ชื่อว่า DivideByZeroException และเราก็ดักตัวนี้ด้วย ดังนั้นมันก็เข้าไปทำงานใน { } ของ catch (ในกรณีไม่ตรง มันก็จะไปหาที่ catch() ต่อๆ ไป แต่ไม่เจอ catch ที่เหมาะสม แต่ไปเจอ code แทนโปรแกรมก็จะโดน TKO ครับ
เมื่อคุณดัก error มันจะได้เป็นตัวแปร ในที่นี้ชื่อว่า e ในนี้มี methods และ properties ให้คุณใช้จำนวนหนึ่ง แต่ที่ใช้บ่อยก็คงมี Message ครับเพื่อบอกรายละเอียดว่า มี error อะไรเกิดขึ้น

ในกรณีที่คุณต้องการดัก error ทุกอย่าง ไม่ว่ามี error อะไรเกิดขึ้นให้เข้า catch block ที่กำหนด ให้ใช้ code แบบนี้ครับ

 

catch(Exception e) {
  
}