วันพุธที่ 17 สิงหาคม พ.ศ. 2559

Exception

ในบทนี้ คุณจะได้เรียนและทำความรู้จักกับ 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 ของ NameNotFoundException

User-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# ไม่มีให้

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Set MongoDB in the windows path environment

  Let’s set MongoDB in the windows environment in just a few steps. Step 1: First download a suitable MongoDB version according to your mach...