ในบทนี้ คุณจะได้เรียนและทำความรู้จักกับ Exception ในภาษา C# รวมถึงการใช้งาน Exception ไลบรารี่ที่ภาษา C# มีให้ และการจัดการและสร้าง Exception แบบกำหนดเองของคุณ
Exception คืออะไร
Exception คือข้อผิดพลาดที่เกิดขึ้นที่เกิดขึ้น ในขณะที่โปรแกรมกำลังทำงานในเงื่อนไขที่ไม่เหมาะสม แล้วโปรแกรมไม่รู้วิธีการจัดการกับข้อผิดพลาดนี้ ทำให้โปรแกรมแสดงข้อผิดพลาดให้เราทราบออกทาง Console และโปรแกรมหยุดทำงานหรือ Crashในบางครั้งโปรแกรมของเราทำงานขึ้นกับ สภาวะแวดล้อมอื่น เช่น การหารตัวเลขด้วย 0 การรับค่ามาจากผู้ใช้ หรือการที่ไม่สามารถเชื่อมต่ออินเตอร์เน็ตได้ ทำให้เกิด Exception ขึ้น เราต้องจัดการเพื่อให้โปรแกรมสามารถที่จะทำงานต่อไปได้ ในภาษา C# คุณสามารถใช้ Exception จากไลบรารี่ทีมีอยู่หรือสร้างขึ้นมาเองได้ โดยมีรูปแบบการใช้งานดังนี้
try { // Statement to execute } catch (ExceptionType1 ex1) { // Handing exception 1 } catch (ExceptionType2 ex2) { // Handing exception 2 } ... catch (ExceptionTypen exn) { // Handing exception n }โดยในบล็อคคำสั่ง
try
เป็นส่วนของการทำงานที่ของโปรแกรม และบล็อคคำสัง catch
เป็นการจัดการกับ exception แต่ละแบบที่เกิดขึ้น โดย Exception
นั้นสามารถเกิดขึ้นได้เพียงหนึ่งอย่างเท่านั้นในขณะหนึ่งเวลาของโปรแกรมการใช้งาน Exception
ต่อไปเป็นตัวอย่างการจัดการ Exception ที่เกิดขึ้น โดยตัวอย่างนี้จะเป็นการใช้ Exception ออบเจ็คDivideByZeroException
จาก namespace system ของภาษา C# โดยเป็นโปรแกรมหารตัวเลขอย่างง่าย โดยโปรแกรมจะรับตัวเลขสองตัวมาจากผู้ใช้และทำการหารusing System; namespace Exception1 { class Program { static void Main(string[] args) { int a; int b; Console.WriteLine("Divider Program"); Console.Write("Enter number a: "); a = Int16.Parse(Console.ReadLine()); Console.Write("Enter number b: "); b = Int16.Parse(Console.ReadLine()); try { Console.WriteLine("The result of a / b is " + (a / b)); } catch (DivideByZeroException ex) { Console.WriteLine("Exception Divide by Zero occur:" + ex); } Console.ReadKey(); } } }จาก ตัวอย่างนั้น เราได้รับค่าตัวเลขสองตัวจากผู้ใช้มาทางคีย์บอร์ด ผู้ใช้สามารถใส่ค่าของตัวเลขใดๆ และหน้าที่ของโปรแกรมคือการนำตัวเลขมาหารและแสดงผลให้กับผู้ใช้
คำสั่ง try catch
การใช้ Exception นั้นจะเริ่มต้นด้วยคำสั่งtry
โดยในบล็อคของคำสั่งนี้จะเป็นส่วนที่คาดว่า Exception จะเกิดขึ้น
โดยในตัวอย่างก็คือการหารตัวเลขด้วย 0
นั่นหมายความว่ามันมีโอกาศที่ผู้ใช้จะกรอกค่า b เป็น 0 ได้try { Console.WriteLine("The result of a / b is " + (a / b)); }และต่อมาในบล็อคของคำสั่ง
catch
เป็นส่วนในการจัดการเมื่อเกิด Exception ขึ้น
นั่นคือเมื่อผู้ใช้ใส่ตัวเลขสำหรับ b เป็น 0 โปรแกรมจะทำการ throw
exception มายังบล็อคนี้ catch (DivideByZeroException ex) { Console.WriteLine("Exception Divide by Zero occur:" + ex); }และข้างล่างเป็นตัวอย่างของโปรแกรม เมื่อผู้ใช้กรอกตัวเลขที่สามารถการกันได้ นั่นก็คือตัวหารไม่เป็น 0
Divider Program Enter number a: 15 Enter number b: 3 The result of a / b is 5แหละ ข้างล่างเป็นตัวอย่างเมื่อผู้ใช้กรอกตัวหารเป็น 0 โปรแกรมจะ throw exception ไปยังบล็อคของคำสั่ง catch และแสดงผลของ exception ในออบเจ็ค
ex
ออกมา ซึ่งเกิดจากการ Override ในเมธอด ToString
ของออบเจ็ค คุณจะได้เรียนในต่อไปDivider Program Enter number a: 10 Enter number b: 0 Exception Divide by Zero occur: System.DivideByZeroException: Attempted to divide by zero...จาก ตัวอย่างข้างบนคุณคิดว่ามันเพียงพอสำหรับการจัดการ Exception ที่น่าจะเกิดขึ้นแล้วใช่ไหม คำตอบคือไม่ใช่ ยังมีอย่างอื่นที่สามารถเกิดขึ้น นั้นคือในตอนที่ผู้ใช้กรอกข้อมูลประเภทอื่นเข้ามาที่ไม่ใช่ตัวเลข ใช่แล้วคุณควรจะจัดการกับมันเพื่อให้โปรแกรมของคุณทำงานได้ดีที่สุด โดยการใช้ Exception ออบเจ็ค
FormatException
using System; namespace Exception1 { class Program { static void Main(string[] args) { int a; int b; bool succeed; Console.WriteLine("Divider Program"); try { Console.Write("Enter number a: "); a = Int16.Parse(Console.ReadLine()); Console.Write("Enter number b: "); b = Int16.Parse(Console.ReadLine()); try { Console.WriteLine("The result of a / b is " + (a / b)); } catch (DivideByZeroException ex) { Console.WriteLine("Exception Divide by Zero occur: " + ex); } } catch (FormatException ex) { Console.WriteLine("You must enter numbers."); } finally { Console.WriteLine("The program always enter finally block."); } Console.ReadKey(); } } }ใน ตอนนี้เราได้พัฒนาโปรแกรมของเราให้จัดการกับข้อมูลที่ไม่ถูกต้องได้แล้ว นั่นคือเมื่อผู้ใช้หรอกอย่างอื่นที่ไม่ใช้ในรูปแบบของตัวเลข เพราะการใช้เมธอด
Int16.Parse()
เป็นเมธอดในการแปลง string
ไปเป็น Integer นั้นจะทำให้เกิด Exception
ขึ้นในกรณีที่ข้อมูลที่นำมาแปลงไม่ใช่ตัวเลข คุณเห็นบางอย่างซับซ้อนขึ้น
นั่นคือเราได้ทำการซ้อน Exception เพราะว่าแน่นอน
มันสามารถซ้อนกันได้เหมือนกับคำสั่ง If อยู่แล้ว
และคุณเห็นคำสั่งใหม่เพิ่มเข้ามาคือ finally
คำสั่ง Finally
ใน บล็อคของคำสั่ง Finally นั้นจะเป็นบล็อคที่โปรแกรมจะเข้ามาทำงานเสมอ หลังจากที่มันทำงานในบล็อคของ try เสร็จ หรืออาจจะเป็นในบล็อคของ catch ก็ตาม มันมักจะใช้กับการทำงานที่มีโอกาสเกิดข้อผิดพลาดขึ้นในคำสั่ง try แต่ไม่มีการ Throw Exception เช่นการทำงานกับไฟล์ การเปิดไฟล์นั้นไม่ว่าจะเปิดสำเร็จหรือไม่ ก็ไม่เกิด Exception ดังนั้นคำสั่ง Finally ใช้สำหรับจัดการเมื่อการทำงานเสร็จสิ้นหรือไม่เป็น สำหรับตัวอย่างSystem.IO.FileStream file = null; System.IO.FileInfo fileinfo = new System.IO.FileInfo("D:\\marcus.txt"); try { file = fileinfo.OpenWrite(); file.WriteByte(1); } finally { // Check if file is successfully opened if (file != null) { file.Close(); } }
Throwing Exceptions
เมื่อเกิด Exception ขึ้นโปรแกรม จะ Throw exception ไปยัง catch block และในภาษา C# นั้นคุณสามารถใช้คำสั่งthrow
เพื่อ throw exception ไปยัง Exception Handle ที่คุณต้องการได้using System; namespace Exception1 { class Program { static void Main(string[] args) { int index = -1; string[] array = new string[] { "One", "Two", "Three" }; try { if (index > array.Length - 1) throw new IndexOutOfRangeException(); else if (index < 0) throw new ArgumentException(); Console.WriteLine("Your number is " + array[index]); } catch (IndexOutOfRangeException ex) { Console.WriteLine("IndexOutOfRangeException is thrown."); } catch (ArgumentException ex) { Console.WriteLine("ArgumentException is thrown."); } Console.ReadKey(); } } }จาก ตัวอย่างด้านบน เป็นการใช้คำสั่ง throw ในการ throw exception ไปยัง catch block ที่ต้องการ โดยปกตินั้นถ้าหาก index ของอาเรย์ไม่ถูกต้องโปรแกรมจะทำการ throw ไปยัง IndexOutOfRangeException อยู่แล้ว แต่ในตอนนี้เราได้ให้โปรแกรม throw ไปยัง ArgumentException ได้ถ้าหาก index เป็นค่าลบ
Creating Exceptions
บางครั้งคุณ อาจจะต้องการสร้าง Exception ของคุณเพื่อจัดการกับบางอย่างที่ในภาษา C# ไม่มีให้ แน่นอนคุณสามารถทำได้ โดยสร้าง Exception ของคุณขึ้นมาเพื่อจัดการกับปัญหา โดยการสร้างคลาสที่ inherit มาจากคลาสSystem.Exception
using System; using System.Collections.Generic; namespace Exception1 { class Program { static void Main(string[] args) { List<string> names = new List<string>(); names.Add("Marcus"); names.Add("James"); names.Add("Daneil"); string nameSearch = "Thomas"; try { if (!names.Contains(nameSearch)) { throw new NameNotFoundException(nameSearch); } else { Console.WriteLine("Hello " + nameSearch + "!"); } } catch (NameNotFoundException ex) { Console.WriteLine(ex); } Console.ReadKey(); } } public class NameNotFoundException : Exception { string name; public NameNotFoundException() { } public NameNotFoundException(string message) : base(message) { this.name = message; } public NameNotFoundException(string message, Exception inner) : base(message, inner) { } public override string ToString() { return "A person named \"" + this.name + "\" is not found."; } } }จาก ตัวอย่างเป็นการสร้างคลาส exception ของคุณเอง เราเรียกว่า user-defined exception เป็น Exception ในการจัดการในกรณีที่ไม่มีชื่ออยู่ใน List เราใช้คำสั่ง if เพื่อตรวจสอบว่ามีคนที่ชือ Thomas มรลิสต์หรือไม่
if (!names.Contains(nameSearch)) { throw new NameNotFoundException(nameSearch); }ถ้ามีเราก็แสดงการทักทาย และถ้าไม่มีในตอนนี้เราจะทำการ Throw ไปยัง Exception ที่เราได้สร้างขึ้น ด้วยคำสั่ง
throw new NameNotFoundException(nameSearch);
และส่ง nameSeach
เป็นพารามิเตอร์สำหรับ constructor ของคลาส ผลลัพธ์ก็คือโปรแกรมทำการ throw ไปยัง catch block ของ NameNotFoundExceptionUser-Defined Exceptions
เราได้สร้างคลาส Exception ที่มีชื่อว่าNameNotFoundException
โดย inherit จากคลาส Exception
ที่อยู่ภายในเนมสเปซ system ของภาษา C# โดยมี constructor 3 แบบ โดย constructor เราใช้ในตัวอย่างคือpublic NameNotFoundException(string message)โดยเก็บค่าของชื่อเก็บไว้ในตัวแปร
name
ของคลาส เพราะว่าใน catch block โปรแกรมหลักนั้น เราได้ใช้คำสั่ง Console.WriteLine(ex);
ซึ่งเป็นการเรียกใช้ตัวแปรออบเจ็ค (object instance) โดยผลลัพธ์ที่ได้จากตัวแปรนั้นจะเป็นค่าที่ได้มากจากเมธอด ToString()
ต่อไปเราได้ทำการ override เมธอด ToString()
เพื่อให้มันแสดงข้อความตามที่ต้องการ (ถ้าคุณไม่ override มันจะแสดงจาก
base คลาสโดย default)public override string ToString() { return "A person named \"" + this.name + "\" is not found."; }และในผลลัพธ์โปรแกรมของเราจะแสดงข้อความ "A person named "Thomas" is not found." เพราะว่าเป็นผลจากเมธอด ToString
ใน บทนี้ คณได้เรียนรู้เกี่ยวกับการใช้งาน Exception ในภาษา C# นอกจากนี้คุณยังสามารถสร้าง Exception ของคุณได้เอง เพื่อจัดงานในงานที่คุณต้องการที่ในภาษา C# ไม่มีให้
ไม่มีความคิดเห็น:
แสดงความคิดเห็น