Thursday, November 9, 2017

C# For Beginners , Part- 41 ( Generics )

আজকে আমরা , Generics নিয়ে কথা বলবো এবং এর উপকারিতা সম্পর্কে জানার চেষ্টা করবো ।। তো চলো , আমরা প্রথমেই একটা ছোট্ট প্রোগ্রাম লিখে আসি ---------------------------------
using System;

using System.Collections.Generic;

   public class Program
    {
        public static void Main()
        {
            bool expression = Calculator.AreEqual(10, 10);
            if(expression)
            {
                Console.WriteLine("They are equal");
            }
            else
            {
                Console.WriteLine("They are not equal");
            }
            Console.ReadKey();
        }
    }
public class Calculator
{
   public static bool AreEqual(int value1,int value2)
   {
       return value1 == value2;
   }
   
}

আমরা , এমন একটা প্রোগ্রাম বানাতে চাচ্ছি যে -- যেটা দুইটা টাইপভ্যালু সমান ( ইকুয়াল ) কি না ??? সেটা চেক করে বলে দিবে ।। তো , সেই অনুযায়ি - একটা ছোট্ট প্রোগ্রাম লিখে ফেললাম ।। আমরা যদি চাই , আমরা দুইটা ক্যারেক্টার এর কম্পেয়ার করবো , তাহলে কিন্তু , পারবো না । কারন, আমাদের এই  AreEqual মেথোডটা কিন্তু শুধু ইন্টিজার ডেটা-টাইপ এর উপরে কাজ করবে ( Coupled With int DataType )  |

তো ধরো , আমি আমার এই মেথোডকে যেকোনো ডেটা-টাইপের জন্যই কাজ করাতে চাই , তাহলে কি করানো যেতে পারে ?? হুম তখনই , আমরা ডেটাটাইপ ইউজ করার বদলে object কীওয়ারড ইউজ করবো , নিচের মতো করে , চলো একটা প্রোগ্রাম দেখেই আসি -----------

using System;

using System.Collections.Generic;

   public class Program
    {
        public static void Main()
        {
            bool expression = Calculator.AreEqual('A', 'B');
            if(expression)
            {
                Console.WriteLine("They are equal");
            }
            else
            {
                Console.WriteLine("They are not equal");
            }
            Console.ReadKey();
        }
    }
public class Calculator
{
   public static bool AreEqual(object value1,object value2)
   {
       return value1 == value2;
   }
   
}

এবার কি লক্ষ করেছো যে ?? আমরা কোনো টাইপ উল্লেখ করি নি AreEqual মেথোডে শুধু  object কিওয়ারড ইউজ করেছি ।  এই কারনে ,আমরা যেকোনো টাইপের প্যারামিটারকেই পাস করাতে পারবো এই মেথোডে ।। তাহলে , দেখো এখন আমাদের এই মেথোড কিন্তু  reusable , এর মানে - যে কোনো ডেটাটাইপের জন্যই ইউজ করতে পারবো ।। শুধু , নির্দিষ্ট ডেটাটাইপের জন্যই নয় ।

আচ্ছা আসলে , এখানে কি ঘটনা ঘটছে ??? আমরা  object ইউজ করার ফলে , যেকোনো ডেটাটাইপ প্যারামিটার হিসেবে পাস করাতে পারছি । মুলত , আমাদের সব ডেটাটাইপই ( int , double , char , string etc ) ডিরেক্টলি / ইনডিরেক্টলি  object  ক্লাস থেকে , ইনহেরিটেড হয়েছে , তাই - আমরা ডেটাটাইপের বদলে object ইউজ করে যেকোনো টাইপের ভ্যালু দেই না কেনো , সেটা অটোমেটিক ডিটেক্ট হয়ে যায় ।  আমরা যখন এই  AreEqual মেথোডে প্যারামিটার পাস করাই , তখন --- আমাদের নরমাল যে টাইপগুলো ( int , double ,char , string etc...) আছে সেগুলো সবগুলোই ভ্যালু টাইপ , কিন্তু AreEqual মেথোডে  object ( একটা ক্লাস , রেফারেন্স টাইপ )   কিওয়ারড থাকার ফলে সব ভ্যালু টাইপগুলোই রেফারেন্স টাইপে কনভার্ট হয় ।। এই ঘটনাকে boxing বলা হয় ।। শুধু একটা কম্পারিসন এর জন্য ,অযথাই এই বক্সিং এর ঘটনা প্রোগ্রামের পারফরম্যান্স কে ডিগ্রেটেড করে দেয় ।।

এ ছাড়াও , আমরা যেমন দুইটা ন্টিজারকে তুলনা করেছি / দুইটা ক্যারেক্টারকে তুলনা করেছি ।। কিন্তু , আমরা যদি চাই তাহলে দুইটা প্যারামিটারের ভেতর একটা'কে ইন্টিজার হিসেবে আরেকটাকে স্ট্রিং হিসেবেও পাস করাতে পারি ।। তুমি কোনো কম্পাইল এররও পাবা না , ঠিকঠাক বিল্ড হবে ( আউটপুট কিন্তু ঠিকঠাক নাও পেতে পারো , মানে - তুমি যদি ,  10 & "10" কে পাঠাও , প্যারামিটার হিসেবে -তাহলে ইকুয়াল দেখাব্র কথা থাকলেও , ইকুয়াল নাও দেখাতে পারে ) কিন্ত , কোনো এরর পাবা না ।। object টাইপের জন্য , যেকোনো ধরনের প্যারামিটার পাস করাতে পারবা ।। এর থেকে আমরা বুহতে পারলাম , আমাদের
AreEqual  মেথোডটা কিন্তু , স্ট্রংলি-টাইপ থাকলো না !!!


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

using System;

using System.Collections.Generic;

   public class Program
    {
        public static void Main()
        {
            bool expression = Calculator.AreEqual<int>(1,2);
            if(expression)
            {
                Console.WriteLine("They are equal");
            }
            else
            {
                Console.WriteLine("They are not equal");
            }
            Console.ReadKey();
        }
    }
public class Calculator
{
   public static bool AreEqual<T>(T value1,T value2)
   {
       return value1.Equals(value2);
   }
   
}

তাহলে , এখানে আমরা কি কি করলাম ?? আমরা , দুইটা অ্যাংগেল ব্রাকেট দিয়ে  T ইউজ করেছি , তারপর প্যারামিটার দুইটির আগেও  T ইউজ করেছি ।। এর মানে , আমাদের এই মেথোড এর প্যারামিটার যে কোনো টাইপেরই হতে পারে , শুধু তাই নয় -- প্যারামিটারগুলো সব এক টাইপেরই হতে হবে , এর আগেরবার যেমন একটা স্ট্রিং এবং আরেকটা ইন্টিজার টাইপ ইউজ করেও এরর খাও নি , কিন্তু এইবার কিন্তু - এরর খাবা ।।  Calculator.AreEqual<int>(1,2) এর মাধ্যমে আমরা স্পেসিফাই করে দিয়েছি , আমাদের AreEqual মেথোডের টাইপ  T কোন ধরনের হবে ?? এই ক্ষেত্রে আমাদের মেথোডটা স্ট্রংলি টাইপ থাকে , এ ছাড়াও এখানে কোনো বক্সিং / আনবক্সিং ঘটে না , তাই প্রোগ্রামের পারফরম্যান্স কখনো ডিগ্রেটেড হয় না ।। আমরা কিন্তু শুধু মেথোড জেনেরিক্স ইউজ না করে ক্লাস জেনেরিক্স ইউজ করতে পারতাম , চলো দেখে নেই ------------

using System;

using System.Collections.Generic;

   public class Program
    {
        public static void Main()
        {
            bool expression = Calculator<int>.AreEqual(1,2);
            if(expression)
            {
                Console.WriteLine("They are equal");
            }
            else
            {
                Console.WriteLine("They are not equal");
            }
            Console.ReadKey();
        }
    }
public class Calculator<T>
{
   public static bool AreEqual(T value1,T value2)
   {
       return value1.Equals(value2);
   }
   
}


তো যাই হোক , এটা আমরা কেনো ব্যবহার করছি ??? এটার বেসিক নিয়ে আমাদের আর কোনো সমস্যা থাকার কথা নয় _______________




No comments:

Post a Comment