Saturday, October 28, 2017

C# For Beginners , Part-35 ( Exception Handling ,Why ? How ? When ? Basics,Inner Exception,Customize Exception,Exception abuse) )

ধরো তোমার পিসি'র নোটপ্যাড-এ তুমি কিছু একটা সেভ করে রেখেছো । তোমায় সেটা কন্সল স্ক্রিনে দেখাতে চাচ্ছো , তাহলে কি করবে ?? চলো ছোট একটা প্রোগ্রাম দেখে আসি ।
ধরো , তুমি joy1 নামে একটা ফাইল সেইভ করে রেখেছো নোটপ্যাডে ।। এখন সেটাকে সরাসরি সেখান থেকে কন্সল স্ক্রিনে শো করাতে চাও তাহলে -----------------------

using System;
using System.IO;

public class Joy
{

    public static void Main()
    {

        StreamReader streamreader = new StreamReader(@"C:\Users\Joy-PC\Documents\joy1.txt");
        Console.WriteLine(streamreader.ReadToEnd());
        streamreader.Close();
        Console.ReadKey();
    }
}


এখানে আমরা ,  using System.IO আগেই ব্যবহার করে নিয়েছি ।। কারণ , StreamReader ক্লাস'টি System.IO নামক নেইমস্পেইস এর অন্তর্ভুক্ত । তারপর , আমরা C:\Users\Joy-PC\Documents\joy1.txt এর মাধ্যমে সেই ফাইল এর ডিরেক্টরি লিখে ফেলি , StreamReader ক্লাস'টির কন্সট্রাক্টর এর মধ্যে  ।। আর , শুধু ব্ল্যাকস্ল্যাস ( \  ) আমরা ডাবল কোটেশন এর ভেতরে ইউজ করতে পারবো না , এটা একটা এসকেপ সিকুয়েন্স ক্যারেক্টার  । তাই , আগে @ ব্যবহারকরেছি ।। তারপর সেটা আমরা প্রিন্ট করেছি ।। আমরা এখানে , streamreader.Close() ব্যবহার এর মাধ্যমে , StreamReader ক্লাসের যে নতুন অবজেক্ট ক্রিয়েট করেছি তার সকল রিসোরস রিসোর্স মেমোরি থেকে ক্লিন করার জন্য ব্যবহার করেছি ।।

যাই হোক আমরা আজ যে বিষয়টি নিয়েই আলোচনা করবো সেটা হলো - Exception Handling | Exception হলো এক প্রকার Unforeseen Error যেটা আমাদের প্রোগ্রাম যখন এক্সিকিউট হয় , তখন ঘটে ।। ধরো , তুমিই তোমার  joy1.txt ফাইলের নাম চেইঞ্জ করে অন্য একটা নাম দিলে ।। তারপর উপরের কোড রান করো ,তাহলে কি হবে ??

স্ক্রিনে তুমি , কিছু হিজিবিজি লিকা দেখতে পাবে । আসলে এগুলো হলো এরর , যার প্রথমেই তুমি দেখতে পাবে -- "Unhandled Exception:System.IO.FileNotFound Exception..."
তাই না ?? এখানেই কিন্তু তুমি দেখতে পাচ্ছো সেই  Exception  এর কথা । আমরা কিন্তু , এই  "Unhandled Exception  " কে  handle করতে পারি ।। আজকে আমরা এগুলোই শিখবো ।।

আর তাছাড়াও এই  Exception এর যেসব তথ্য আউটুপুট-এ দেখাচ্ছে , এসব আমরা যারা নতুন তারা কিছু না বুঝলেও , এসব কিন্তু খুবই মূল্যবান অনেক তথ্য বহন করে হ্যাকারদের জন্য ।। তাই আমাদের অবশ্যই জানতে হবে ,  Exception  এর তথ্যগুলি কিভাবে ?? handle  করতে পারি ।। চলো একটা কোড দেখে আসি --

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        try
        {
            StreamReader streamreader = new StreamReader(@"C:\Users\Joy-PC\Documents\joy.txt");
            Console.WriteLine(streamreader.ReadToEnd());
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
        Console.ReadKey();
    }
}


আমাদের  .NET ফ্রেমওয়ার্কের খাতিরে -- একটা  Exception  ক্লাস দেয়াই আছে যার বেশ কয়েকটি প্রোপার্টি আছে ।। যার ভেতরে  Message & StackTrace প্রোপারটি মূলত আমাদের এক্সসেপশন সম্পরকে তথ্য ও ভূল প্রোগ্রামের  কতো নাম্বার লাইনে আছে ?? সেটা বলে দিবে ।। এখন তুমি বুঝবে কি করে ? কতো নাম্বার লাইন কোনটা ?? প্রথম প্রথম বুঝতে সমস্যা হতেপারে , সেই জন্য তোমায়
Cntrl+G প্রেইস করলেই ।। একটা ফর্ম আসবে , সেখানে তুমি যতো নাম্বার লিখবে ? তোমায় ততো নাম্বার লাইনে মাউস  এর দাগ চলে যাবে। দেখে নাও ... এখানে আমরা  try ও  catch ব্লক ইউজ করেছি । যদি কোনো এক্সসেপশন নাই থাকতো , তাহলে  catch ব্লকের কোনো কিছু প্রিন্ট হবে না । কিন্তু , try  ব্লকে কোনো এক্সসেপশন থাকলে সেটা catch  ব্লকে প্রিন্ট করবে ।।

এখন একটা জিনিস আমাদের জেনে রাখতে হবে , উপরে যেটা ঘটছে , সেটা মূলত  FileNotFound Exception । এটাও একটা ক্লাস ,যেটা  Exception ক্লাস থেকে ইনহেরিটেড হয়েছে ।। চলো একটু দেখে আসি -----

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        try
        {
            StreamReader streamreader = new StreamReader(@"C:\Users\Joy-PC\Documents\joy.txt");
            Console.WriteLine(streamreader.ReadToEnd());
        }
        catch(FileNotFoundException ex)
        {
            Console.WriteLine("{0} File May Doesn't Exist, Please Check\n\n\n", ex.FileName);

            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
        Console.ReadKey();
    }
}


এখানে আমরা ,  FileNotFoundException  ক্লাস ব্যবহার করেছি ।। যার একটা প্রোপার্টি আছে    FileName নামে ।। যার সাহা্য্যে , আমরা ফাইলের নামটিও শো করাতে পারছি ,যে ফাইল থেকে আমরা রিড করতে চাচ্ছিলাম ।।  প্রোগ্রামটি রান করিয়ে দেখে নাও , আর তারপর আমরা  Message ও  StackTrace প্রোপার্টির দ্বারা অনেক মেসেজ শো করাই ।।   তুমি কি বুঝতে পারছো যে -- একটু একটু করে তুমি   Exception Handling করা শুরু করেছো ।।

নীচের কোড দেখে আসি চলো -------------------------

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        try
        {
            StreamReader streamreader = new StreamReader(@"C:\UsersJoy-PC\Documents\joy.txt");
            Console.WriteLine(streamreader.ReadToEnd());
        }
        catch(FileNotFoundException ex)
        {
            Console.WriteLine("{0} File May Doesn't Exist, Please Check\n\n\n", ex.FileName);

            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
      
        Console.ReadKey();
    }
}


এখানে আমরা কিন্তু , ফাইলের ডিরেক্টরি ইচ্ছে করে আমি বদলে দিয়েছি ,খেয়াল করে দেখো ।। এখন আমি যদি রান করাই তাহলে কি হবে ??? আউটপুটে দেখবে ---DirectoryNotFoundException তাই না ?? এর মানে ?? এটা  FileNotFoundException  নয় ।। তাই তুমি , FileNotFoundException  এর  catch ব্লক দিয়ে DirectoryNotFoundException এক্সশেপশন কে হ্যান্ডল করতে পারবে না । তুমি উপরের কোড রান করে দেখো , তূমি যেটা শো  করাতে চাইছিলে সেটা কিন্তু কনসল স্ক্রিনে দেখাচ্ছে না। একটু ভালো করে খেয়াল করে দেখো ।। 

তাহলে  DirectoryNotFoundException  এর ক্ষেত্রে তুমি কি কি করবে ?? বুঝতেই পারছো , DirectoryNotFoundException  ক্লাস অথবা সবার মাদার ক্লাস Exception ক্লাসও ব্যবহার করতে পারো ।। তবে , DirectoryNotFoundException  ক্লাসের কিন্তু কোনো  FileName প্রোপার্টি নেই , সেদিকে খেয়াল রেখো ।।

এখান থেকে কিন্তু আমরা বড়ো একটা ব্যপার এর বাস্তব রুপ শিখে গেছি , সেটা কি ?? ইনহেরিটেন্স এর কারণে , আমাদের বেইস ক্লাস Exception এর রেফারেন্স ভ্যারিয়েবল যেকোনো স্পেসিফিক ডেরাইভড Exception ক্লাস এর অব্জেক্ট কে পয়েন্ট করতে পারছে ।। এটা কিন্তু ইনহেরিটেন্স এর বড়ো একটা উদাহরণ ।।

আরো একটা বিষয় , মাথায় রাখা উচিত ।সেটা হলো , স্পেসিফিক ক্লাস যেমন FileNotFoundException  ক্লাস কিন্তু এর বেইস ক্লাস Exception এর আগে  বসবে ।। এটা মাথায় রাখতে হবে ।।

একটা বিষয় আরো ক্লিয়ার হওয়া উচিত , সেটা হলো আমরা যখন try ব্লকে  streamreader.Close(); ইউজ করছি , সেটা কি কখনো কাজ করছে ?? নাকি করছে না ?? আসলে এই লাইন আসার
আগেই যদি কখনো Exception হয়ে যায় , তাহলে । তাহলে কিন্তু ঐ লাইন এক্সিকিউট হয় না । এর মানে ,হিপ মেমোরি থেকে এসব রিসোর্স গুলো ফ্রি হয় না ।। যেটা আমাদের অবশ্যই মাথায় রাখা উচিত ।।
তাহলে কি করবো এখোন ?? হুম ,একটা আরো  ব্লক ইউজ করা যায় -যার নাম হলো  finally ব্লক । যার ভেতরে আমরা streamreader.Close(); ইউজ করবো । কারণ , Exception থাকুক আর নাই থাকুক । আমাদের এই  finally ব্লক এক্সিকিউট হবেই ।।
 try

        {
            StreamReader streamreader = new StreamReader(@"C:\UsersJoy-PC\Documents\joy.txt");
            Console.WriteLine(streamreader.ReadToEnd());
            streamreader.Close();
        }

চলো  আমরা একবার একটা প্রোগ্রাম দেখে আসি  , এটা নিয়ে ।।
using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        StreamReader streamreader = null;
        try

        {
             streamreader = new StreamReader(@"C:\UsersJoy-PC\Documents\joy.txt");
            Console.WriteLine(streamreader.ReadToEnd());
            streamreader.Close();
        }
            catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.WriteLine("Finally block Executed!!");
            Console.ReadKey();
            streamreader.Close();
        }
      
        Console.ReadKey();
    }
}

 এটা  Exception সহ  ছিলো ।। এখন একটা Exception ছাড়া কোড লিখে দেখি ----  finally ব্লক এক্সিকিউট হয় কি না ?? চলো --------------

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        StreamReader streamreader = null;
        try

        {
             streamreader = new StreamReader(@"C:\Users\Joy-PC\Documents\joy1.txt");
            Console.WriteLine(streamreader.ReadToEnd());
            streamreader.Close();
        }
            catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.WriteLine("Finally block Executed!!");
            Console.ReadKey();
            streamreader.Close();
        }
      
        Console.ReadKey();
    }
}

 এবার  Exception ছাড়াই দেখলাম , দুই ক্ষেত্রেই কিন্তু আমাদের finally ব্লক এক্সিকিউট হয়েছে । সো , আমরা এই ব্লক ইউজ করবো  ।।   আবার অনেক Exception এর ক্ষেত্রে যদি StreamReader ক্লাসের অবজেক্ট  ফাইল থেকে রিড নাই করতে পারে  ( মানে , Exception থাকে )  তাহলে , StreamReader ক্লাসের অব্জেক্ট নালই থেকে যায় ।। তাই , finally ব্লকের এক্সিকিউট হয় না । তাই আমরা জিনিসটাকে আরো একটু সুন্দরভাবে এইভাবে লিখতে পারি --

finally
        {
              if( streamreader!=null){
            Console.WriteLine("Finally block Executed!!");
            Console.ReadKey();
            streamreader.Close();
                   }
        }

আশা করি , বিষয়টা খুবই স্পষ্ট হয়েছে ।।  এখানে আরো একটি প্রশ্ন মনের ভেতরে আসতেই পারে , আমাদের - সেটা হলো ,আমরা শুধু শুধু আরো একটা finally নামে একটা ব্লক খুলে কোডগুলো এক্সিকিউট করালাম কেনো ?? আমরা তো এই ব্লকের ভেতরের কোডগুলো এমনিতেই লিখতে পারতাম , এই ব্লক ছাড়া - তাতে কি অসুবিধা হত ??

প্রশ্নটি খুবই ভালো প্রশ্ন , কিন্তু - একটি কথা জেনে রাখা উচিত ।। যদি , আমাদের কোনো এক ধরণের  Exception হয়েই থাকে এবং সেটার ফলে StreamReader ক্লাসের অব্জেক্ট নাল নাই থাকে । তাহলে ,ক্যাচ ব্লকে ঢোকার পরে এটা এর পরের আর কোনো কোড এক্সিকিউট করতে দিবে না , তাই আমরা সবসময় finally ব্লকই ইউজ করবো ,এটা খুবই ভালো একটা অভ্যাস ।।

আচ্ছা যাই হোক , এবার আমরা একটু বিরতি নিয়ে তারপর এরপরের আলোচনা শুরু করবো ।। তোমরা যারা আছো , তারা উপরের অংশটুকুই আগে ভালো করে বোঝার টড়াই করো , তারপর নিচের অংশটুকু বোঝা যাবে ।।

চলো এবার আমরা একটা সংখ্যাকে শূণ্য দ্বারা ভাগ দিয়ে দেখি , কি ধরনের Exception হয় ??? নীচে কোড দেখে আসি চলো ---

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
       
        try

        {
            int a = Convert.ToInt32(Console.ReadLine());
            int b = Convert.ToInt32(Console.ReadLine());
            int result = a / b;
            Console.WriteLine(result);
           
        }
            catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
      
      
        Console.ReadKey();
    }
}

এখন ধরো , এটা কোন ধরনের  Exception ?? সেটা আমরা যে ফাইল থেকে এতদিন রিড করেছি , সেই ফাইলে রাইট করি ( লিখে ফেলি ) ।। দেখি চলো কোড ----------

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
       
        try

        {
            int a = Convert.ToInt32(Console.ReadLine());
            int b = Convert.ToInt32(Console.ReadLine());
            int result = a / b;
            Console.WriteLine(result);
           
        }

            catch(Exception ex)
        {
            string filepath = @"C:\Users\Joy-PC\Documents\joy1.txt";
                 StreamWriter sw=new StreamWriter (filepath);
                 sw.WriteLine(ex.GetType().Name);
                 sw.Close();
          
        }
      
      
        Console.ReadKey();
    }
}


এখানে আমরা কোন ধরনের Exception ? সেটা জানার জন্য  GetType() মেথোড এবং এর  প্রোপার্টি  Name ইউজ করছি ।। এখন উপরের কোড রান করে - তারপর ঠিকঠাক দুইটি আউটপুট এর প্রথমটি যেকোনো নাম্বার দাও আর , সেকেন্ড নাম্বারটি শূণ্য দাও । তাহলে তুমি , তারপরে তোমার যে ফাইলে সেইভ করছো - সেখানে গিয়ে দেখো । অটোমেটিক , তোমার ঐ ফাইলে এটা যে ধরনের  Exception ( DivideByZeroException ) লিখা উঠে গেছে ।। এভাবে আমরা অনেক কিছুই ফাইলে লিখাতে পারবে , যেমন  Message প্রপার্টি সহ অনেককিছুই  | ।

আচ্ছা এবার আসো পুরোনো কথায় - আমি যে ফাইল ডিরেক্টরি লিখেছি , সেটা ভুল লিখতে চাই এর মানে ( FileNotFound Exception) ঘটাতে চাই চলো দেখি কি করা যায় ???

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
       
        try

        {
            int a = Convert.ToInt32(Console.ReadLine());
            int b = Convert.ToInt32(Console.ReadLine());
            int result = a / b;
            Console.WriteLine(result);
           
        }

            catch(Exception ex)
        {
            string filepath = @"C:\Users\Joy-PC\Documents\joy.txt";
            if (File.Exists(filepath))
            {
                StreamWriter sw = new StreamWriter(filepath);
                sw.WriteLine(ex.GetType().Name);
                sw.Close();
            }
            else
            {
                throw new FileNotFoundException(filepath + "is not found", ex);
            }
          
        }   
    }
}

 উপরের কোডটি রান করে দেখো । তাহলে কি দেখলে ??? আমাদের উদ্দেশ্য ছিলো  DivideByZeroException , কিন্তু - আমরা নতুন একটা উটকো ঝামেলা  FileNotFoundException । কিন্তু এই দুইটা  Exception আনার পরে ।। আমরা কোনোটাই হ্যান্ডেল করতে পারছি না ।।

 সেকেন্ডটার জন্য , প্রথম Exception টাও এখন ফাইলে রাইট করে পারছি না । তো চলো , এই সমস্যা থেকে কিভাবে ,উদ্ধার পাওয়া যায় ?? সেই চেষ্টা করি ।। আচ্ছা একটা জিনিস ক্লিয়ার হয়ে নেই যে - আমাদের একদম প্রথম Exception ছিলো DivideByZeroException , তাই না ?? আর তারপরের সেকেন্ড  Exception টা হলো --  FileNotFoundException ।। প্রোগ্রামের ভাষায় আমরা প্রথম টাকে InnerException বলবো , আর পরেরটাকে Current Exception বলবো , ঠিক আছে ??? চলো এবার আসল কাজটা সেরে আসি --

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        try
        {
            try
            {
                int a = Convert.ToInt32(Console.ReadLine());
                int b = Convert.ToInt32(Console.ReadLine());
                int result = a / b;
                Console.WriteLine(result);

            }

            catch (Exception ex)
            {
                string filepath = @"C:\Users\Joy-PC\Documents\joy.txt";
                if (File.Exists(filepath))
                {
                    StreamWriter sw = new StreamWriter(filepath);
                    sw.WriteLine(ex.GetType().Name);
                    sw.Close();
                }
                else
                {
                    throw new FileNotFoundException(filepath + "is not found", ex);
                }

            }
        }
        catch(Exception es)
        {
            Console.WriteLine("Current Exception = {0}", es.GetType().Name);
            Console.WriteLine("Inner Exception = {0}", es.InnerException.GetType().Name);
            Console.ReadKey();
        }
       
    }
}

 তাহলে এখানে আমরা আরো একটা try & catch ইউজ করলাম , কেনো ?? কারণ আমরা  যদি  প্রথমেই   Exception পাই , তাহলে সেটাকে  catch  করার জন্য ভেতরে  একটা catch  ব্লক ইউজ করেছি , তাই না ?? কিন্তু যখন , সেই  catch ব্লকেও  Exception পাবো , তখন কি করবো , তাই আরো এই পুরোটাকেই একটা try ব্লকে ঢুকিয়ে দিয়েছি এবং তারপর আরো একটা  catch  ব্লক বাইরে ইউজ করেছি ।।  আশা করি এইটুকু বুঝতে পেরেছো ।। এখন , নতুনত্ব বলতে আমরা ভেতরের ক্যাচ ব্লকের Exception এর জন্য , InnerException ইউজ করেছি , এইটুকুই । এখানে কিন্তু একটা কাহিনি আছে  throw new FileNotFoundException(filepath + "is not found", ex); এর মাধ্যমে কিন্তু আসলে আমরা ওই প্রথম Exception এর রেফারেন্স ভ্যারিয়েবল ( অব্জেক্ট ) আমাদের নতুন বাইরের Exception ক্লাসে পাঠিয়ে দিয়েছি । যা InnerException তে পয়েন্ট করা আছে , এই কারণেই --- es.InnerException.GetType().Name লিখলে সেই ভেতরের  Exception এর টাইপ পেয়ে যাচ্ছো । আশা করি , বিষয়টা ক্লিয়ার হয়েছে ।।


আচ্ছা একটা বিষয় পরিষ্কার করেই নেই , তুমি যদি শুধু আউটার  Exception শো করাতে চাও , তাহলে কি করতে হবে ?? চলো দেখে আসি --

using System;

using System.IO;

public class Joy
{

    public static void Main()
    {
        try
        {
            try
            {
                int a = Convert.ToInt32(Console.ReadLine());
                int b = Convert.ToInt32(Console.ReadLine());
                int result = a / b;
                Console.WriteLine(result);

            }

            catch (Exception ex)
            {
                string filepath = @"C:\Users\Joy-PC\Documents\joy.txt";
                if (File.Exists(filepath))
                {
                    StreamWriter sw = new StreamWriter(filepath);
                    sw.WriteLine(ex.GetType().Name);
                    sw.Close();
                }
                else
                {
                    throw new FileNotFoundException(filepath + "is not found");
                }

            }
        }
        catch(Exception es)
        {
            Console.WriteLine("Current Exception = {0}", es.GetType().Name);
            if (es.InnerException != null)
            {
                Console.WriteLine("Inner Exception = {0}", es.InnerException.GetType().Name);
            }
            Console.ReadKey();
        } 
    }
}

 এখানে , যেহেতু আমরা শুধু একটা মাত্র মানে , সেকেন্ড'টা শো করাতে চাই । তাহলে ভেতরের কন্সট্রাক্টরে ওই ( অরিজিনাল / ইনার )  Exception এর রেফারেন্স ভ্যারিয়েবল পাস করাবো না । আর এইদিকে , যদি আমি প্যারামিটার কনস্ট্রাক্টরে পাস না করাই ।। তাহলে এদিকে আমাদের বাইরের  Exception ক্লাসের গুরুত্বপূর্ণ একটা প্রোপার্টি  InnerException টা নাল থাকবে , আর তাই আমি একটা  if স্টেইটমেন্ট ইউজ করে , চেইক করে দেখালাম  es.InnerException != null যদি খালি না হয় , তাহলেই শুধুমাত্র  Console.WriteLine("Inner Exception = {0}", es.InnerException.GetType().Name); লাইন প্রিন্ট করবে  অন্যথায় প্রিন্ট করবে না  ।।  আশা করি বিষয়গুলো আরো ক্লিয়ার হচ্ছে ।।

আচ্ছা এখন কিছুটা বিরতি নিয়ে আমরা এর পরের বিষয়গুলো আলোচনা করবো , এর পরের আলোচনা দেখার আগে ---- আগেরটুকু ভালো করে পড়ে ও বুঝে নেয়া উচিত ।।


আমরা , আমাদের  Exception এর সময় যে যে মেসেজ শো করে সেটা এক এক Exception অনুযায়ী এক এক রকম , এখানে আমাদের কোনো হাত নেই , আমরা শুধু কখন কোনটা দেখাবে ?? শুধু এইটুকুই হ্যান্ডল করতে পারি ।।  কিন্তু আমরা যদি কখনো নিজে নিজেই নতুন নতুন  Exception ক্রিয়েট করে কাস্টমাইজ করতে পারতাম  ! তাহলে ভালৈ হতো , চলো দেখে আসি ।।

এটা দেখার আগে , ইনহেরিটেন্স ও এক্সশেপশন নিয়ে বেসিক একদম ক্লিয়ার থাকতে হবে , না হলে এই বিষয়টা একদমই অন্যরকম লাগবে ।। চলো ......।।


প্রথমে আমরা একটা ক্লাস খুলে , সেটার বেইস ক্লাস হিসেবে Exception ক্লাস বসিয়ে দেবো , অন্যথায় আমরা আমাদের মতো করে কাজ করাতে পারবো না । তারপর , আমরা তিনটা কন্সট্রাক্টর ক্রিয়েট করবো ।। আগে আমরা , throw new Exception(); লিখে ভেতরে কিছু লিখলেই শো করাতো , কারণ এদের ডিফল্ট কন্সট্রাক্টর আছে , কিন্তু আমরা নতুন যে নতুন  Exception ক্লাস বানিয়েছি , তাতে --
কোনো ডিফল্ট কন্সট্রাক্টর তো নেই তাই আমরা , আমাদের নতুন ক্লাসের বেইস ক্লাস এর কন্সট্রাক্টরকেই ইউজ করবো , তাহলে কষ্ট করে আর লিখতে হবে না ।

  public class UserLoggedInException :Exception
    {
        public UserLoggedInException():base()
        {

        }
        public UserLoggedInException(string Message):base(Message)
        {

        }
        public UserLoggedInException(string Message,Exception innerException):base(Message,innerException)
        {

        }
    }

আমরা শুধু কাস্টমাইজই নয় , আমাদের বানানো Exception ক্লাসের যদি কখনো  innerException ট্র্যাক করানোরও প্রয়োজন পড়ে , তখন আমরা তিন নাম্বার কন্সট্রাক্টর দিয়ে শো করাতে পারবো ।।
আচ্ছা এখন একদমই নতুন একটা বিষয় নিয়ে জানবো , সেটা হলো ---------------- অ্যাপ্লিকেশন ডমেইন । আমাদের এই বানানো ক্লাসটি সাধারণত তখনই কাজ করবে ,যখন সেইম অ্যাপ্লিকেশন ডোমেইন থাকবে ।। এর মানে , ধরো - আমার দুইটা  অ্যাপ্লিকেশন আছে একটার নাম  A & আরো একটার নাম হলো  B  | এই অ্যাপ্লিকেশন দুইটি  একে অপরের সাথে কথা বলতে চায় , তাহলে ?? কি করতে হবে ?? A অ্যাপ্লিকেশনের অবজেক্টগুলোকে B অ্যাপ্লিকেশনের যে বাউন্ডারি আছে , সেটা ক্রস করতে হবে । আর এই জন্য দুইটা  অ্যাপ্লিকেশন এরই অব্জেক্টগুলোকে সিরিয়ালাইজেশন করতে হবে , তাহলে তুমি যদি তোমার অব্জেক্ট গুলোকে এক অ্যাপ্লিকেশন ডোমেইন থেকে অন্য অ্যাপ্লিকেশন ডোমেইন-এ মুভ করাএ চাও তাহলে একটা প্যাকেজ আকারে একটা থেকে আরেকটায় মুভ করতে পারে , এই জন্য অব্জেক্টগুলোকে সিরিয়ালাইজেশন করতে হবে । তাহলে চলো সিরিয়ালাইজেশন  করে এর জন্য আরো একটা কন্সট্রাক্টর ক্রিয়েট করে ফেলি ----

using System;
using System.IO;
using System.Runtime.Serialization;

public class Joy
{

    public static void Main()
    {
        throw new UserLoggedInException("User Is already Logged In , No Duplicate ");
           
        }
    [Serializable]
    public class UserLoggedInException :Exception
    {
        public UserLoggedInException():base()
        {

        }
        public UserLoggedInException(string Message):base(Message)
        {

        }
        public UserLoggedInException(string Message,Exception innerException):base(Message,innerException)
        {

        }
        public UserLoggedInException(SerializationInfo info,StreamingContext context ):base(info,context)
        {

        }
    }
    }

নতুনত্বের মধ্যে আমরা নতুন সিস্টেম ইঙ্কলুড করেছি ------খেয়াল করে দেখে নাও , আপাতত এই  সিরিয়ালাইজেশন  নিয়ে না ভাবলেও চলবে , বাট একটু বেসিক জেনে রাখা ভালো ।।

সব শেষে আমাদের আরো একটা বিষয় ক্লিয়ার হওয়া উচিত যে , এই  Exception এর শুধু শুধু ব্যবহার যেনো না করি ।। যেমন আমরা ,নিচের মতো করে যেনো না করি ।

using System;
using System.IO;
using System.Runtime.Serialization;

public class Joy
{

    public static void Main()
    {
        try
        {
            int a = Convert.ToInt32(Console.ReadLine());
        }
        catch(Exception ex)
        {
            Console.WriteLine("InputFormat Is Not Correct");
            Console.ReadKey();
        }
           
        }
  
    }
এরকমভাবে খুব শজেই আমরা লিখতে পারি , বাট এইসব ছোটখাট বিষয়ে  Try.Parse মেথোড ইউজ করলেই পারি , তা সত্ত্বেও -- শুধু শুধু  Exception ইউজ করা ঠিক হবে না ।। চলো , Try.Parse  মেথোড দিয়ে করে আসি একবার -----------

using System;
using System.IO;
using System.Runtime.Serialization;

public class Joy
{

    public static void Main()
    {
            int result = 0;
            bool IsPossible = Int32.TryParse(Console.ReadLine(),out result);
            if(IsPossible)
            {
                Console.WriteLine("Your Input Is {0}", result);
            }
            else
            {
                Console.WriteLine("Input Format Isn't Correct");
            }
       

           
        }
  
    }

আশা করি বুঝতে পেরেছো , এসব ক্ষেত্রে আমরা শুধু শুধু  Exception ইউজ করবো না ।। যাই হোক আজ এইটুকুই ---------------------------------------























No comments:

Post a Comment