আজকে আমরা Equals() মেথোড নিয়ে কথা বলবো ।। ধরো , আমরা দুইটা সংখ্যার চেক করে দেখবো সমান কি না ?? যদি সমান হয় , তাহলে আউটপুট-এ True আর না হলে আউটপুট-এ False | এই বিষয়টিই , আমরা এনাম দিয়ে করে আসি , তাহলে ওটাও প্র্যাকটিস হয়ে গেলো একটু ------------
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Direction d1 = Direction.East;
Direction d2 = Direction.West;
Console.WriteLine(d1 == d2);
Console.WriteLine(d1.Equals(d2));
Console.ReadKey();
}
}
public enum Direction
{
East=1,
West=2
}
}
আচ্ছা আমরা একটা এনাম ক্রিয়েট করেছি , যার ইলিমেন্ট দুইটা ।। তারপর , তাদের মান চেক করেছি , যদি সমান হয় তাহলে True আর না হলে False দেখাবে ।। এখানে আমরা আউটপুটের জনয দুইটা পদ্ধতি ইউজ করেছি , একটা d1 == d2 , আরেকটা d1.Equals(d2) ।। তো দুইটাতেই আমাদের একই আউটপুট দেখাচ্ছে , খুবই ভালো কথা - কিন্তু আমরা এই দুইটার মধ্যে পার্থক্য বুঝতে পারছি না ।। তো চলো , আরেকটু এগিয়ে যাই , তাহলে আসতে আসতে সব বুঝতে পারবো ।। নতুন আরেকটা কোড দেখি ------------------
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = C1;
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
}
}
এখানে আমরা কি করলাম ?? একটা ক্লাসই ক্রিয়েট করে ফেললাম । । তারপর মেইন মেথোড-এ একই ক্লাসের দুইটি রেফারেন্স ভ্যারিয়েবল ( C1 ও C2 ) ক্রিয়েট করলাম , কিন্তু আমাদের কিন্তু এটা মাথায় রাখতে হবে এই দুইটা রেফারেন্স ভ্যারিয়েবলই কিন্তু একটা অব্জেক্টকে পয়েন্ট করছে ।। তাই , আমি যখন রেফারেন্স টাইপ গুলোকে কম্পেয়ার করাই তখন যেহেতু দুইটা রেফারেন্স ভ্যারিয়েবল একই অব্জেক্টকে পয়েন্ট করছে , তাই তাদের সমান ধরে নেয়া হয় , আর তাই আউটপুট True আসবে , আর দুইটারই একই অব্জেক্ট পয়েন্ট করা থাকলে , অবশ্যই তাদের মানও সমান হবে ।।
আচ্ছা , এবার আমরা একই ক্লাসের দুইটা রেফারেন্স ভ্যারিয়েবল ক্রিয়েট করবো , সাথে দুইটা অবজেক্টও ।। চলো দেখি কি হয় ????????????????
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = new Customer();
C2.FirstName = "Nayeem";
C2.LastName = "Shahriar";
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
}
}
কোডটি রান করে দেখো , কি আউটপুট আসে ??
এবার কি হলো ?? বলো তো দেখি ?? হুম আমাদের দুই ক্ষেত্রেই একই নাম ব্যবহার করেছি , তারপরো আমাদের এক দেখালো না !! এর কারণ , নিশ্চই বুঝতে পেরেছো ইতিমধ্যে ।। আমরা দুই দুইটা আলাদা আলাদা অব্জেক্ট ক্রিয়েট করেছি সাথে সাথে দুই দুইটা আলাদা আলাদা রেফারেন্স ভ্যারিয়েবল । যখন আমরা , আলাদা আলাদা ভ্যারিয়েবল চেক করাতে গেলাম , তখনই প্রথম ধাক্কাতে হেরে গেলাম , কারণ দুইটা ভ্যারিয়েবলই আলাদা আলাদা অব্জেক্টকে পয়েন্ট করছে ।। তাই সেখান থেকেই , ধরে নেয়া হয়েছে যে তারা সমান নয় , এই কারণে - আউটপুটে False পেয়েছি ।।
এখন এই সমস্যা থেকে বাচতে , আমাদের সাহায্য করবে আমাদের Equals() মেথোড ।। তার ডিফল্টভাবে যে ভারচুয়াল মেথোড আছে , তার উপরে আমরা ওভাররাইড করার সুযোগ আছে ,আমরা এখন এই সুযোগ ব্যবহার করবো ।।
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = new Customer();
C2.FirstName = "Nayeem";
C2.LastName = "Shahriar";
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
public override bool Equals(object obj)
{
if(obj==null)
{
return false;
}
if(!(obj is Customer))
{
return false;
}
return this.FirstName == ((Customer)obj).FirstName && this.LastName == ((Customer)obj).LastName;
}
public override int GetHashCode()
{
return this.FirstName.GetHashCode() ^ this.LastName.GetHashCode();
}
}
}
তো , আমরা ঠিকঠাকভাবেই সেই সুযোগ ব্যবহার করেছি ।। যদি , আমরা Equals মেথোদের মধ্যে object টাইপে যে পযারামিটার পাঠাবো , সেটা যদি নাল হয় , তাহলে রিটার্ন তো ভুল হবেই । আর , যদি আমাদের প্যারামিটার হয় অন্য কোনো ক্লাসের টাইপের !! তাহলে তো , কখনো ভিন্ন কোনো টাইপের জিনিস কম্পেয়ার করা হয় না , তাই ভুল হবে । [ !(obj is Customer) ]
আর তারপর নামগুলো সমান কি না ?? সেটা চেক করে , তারপর রিটারন করবো [ return this.FirstName == ((Customer)obj).FirstName && this.LastName == ((Customer)obj).LastName;]
আর আমাদের ওয়ারনিং এড়ানোর জন্য , আমরা যখন Equals মেথোডের ওভাররাইড করবো , তখন - GetHashCode() মেথোডেরও ওভাররাইড করবো , এই মেথোড এক ধরনের হ্যাশকোড প্রদান করে যা , সাধারণত এক ধরণের নিউমেরিক ভ্যালু যেটা একটা অব্জেক্ট এর আইডেনটিফেকিশেন হিসেবে কাজ করে , এর সাহায্যে আমরা - দুইটি অব্জেক্ট এর ইকুয়ালিটি চেক করতে পারি খুব এফিশিয়েন্ট ভাবে ।। দুইটা অব্জেক্ট সমান হলে তাদের হ্যাশকোডও সমান হয় , বাট দুইটা হ্যাশকোড সমান হলেই যে সেই অব্জেক্ট দুটো সমান হবে , তা কিন্তু নয় !! দুইটা অসমান অব্জেক্ট এরও হ্যাশকোড সমান হতে পারে !!!
আসলে , আমরা যখন এই ইকুয়াল মেথোড কল করে , দুইটা অব্জেক্ট এর ইকুয়ালিটি চেক করি তখন অটোমেটিকভাবেই .GetHashCode মেথোড কল করে , হ্যাশ কোড বের করে চেক করে , তাই আমরা
ইকুয়াল মেথোড ইউজ করলে , সাথে সাথে GetHashCode() মেথোডও অভাররাইড করে দেবো , যদিও আপাতভাবে আমাদের কাছে , এই মেথোড এর কোনো কাজ নেই ।।
এই বিষয়ে পরবরতিতে বিস্তারিত কথা বলবো ,
আজ কে আর নয় -----------------------
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Direction d1 = Direction.East;
Direction d2 = Direction.West;
Console.WriteLine(d1 == d2);
Console.WriteLine(d1.Equals(d2));
Console.ReadKey();
}
}
public enum Direction
{
East=1,
West=2
}
}
আচ্ছা আমরা একটা এনাম ক্রিয়েট করেছি , যার ইলিমেন্ট দুইটা ।। তারপর , তাদের মান চেক করেছি , যদি সমান হয় তাহলে True আর না হলে False দেখাবে ।। এখানে আমরা আউটপুটের জনয দুইটা পদ্ধতি ইউজ করেছি , একটা d1 == d2 , আরেকটা d1.Equals(d2) ।। তো দুইটাতেই আমাদের একই আউটপুট দেখাচ্ছে , খুবই ভালো কথা - কিন্তু আমরা এই দুইটার মধ্যে পার্থক্য বুঝতে পারছি না ।। তো চলো , আরেকটু এগিয়ে যাই , তাহলে আসতে আসতে সব বুঝতে পারবো ।। নতুন আরেকটা কোড দেখি ------------------
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = C1;
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
}
}
এখানে আমরা কি করলাম ?? একটা ক্লাসই ক্রিয়েট করে ফেললাম । । তারপর মেইন মেথোড-এ একই ক্লাসের দুইটি রেফারেন্স ভ্যারিয়েবল ( C1 ও C2 ) ক্রিয়েট করলাম , কিন্তু আমাদের কিন্তু এটা মাথায় রাখতে হবে এই দুইটা রেফারেন্স ভ্যারিয়েবলই কিন্তু একটা অব্জেক্টকে পয়েন্ট করছে ।। তাই , আমি যখন রেফারেন্স টাইপ গুলোকে কম্পেয়ার করাই তখন যেহেতু দুইটা রেফারেন্স ভ্যারিয়েবল একই অব্জেক্টকে পয়েন্ট করছে , তাই তাদের সমান ধরে নেয়া হয় , আর তাই আউটপুট True আসবে , আর দুইটারই একই অব্জেক্ট পয়েন্ট করা থাকলে , অবশ্যই তাদের মানও সমান হবে ।।
আচ্ছা , এবার আমরা একই ক্লাসের দুইটা রেফারেন্স ভ্যারিয়েবল ক্রিয়েট করবো , সাথে দুইটা অবজেক্টও ।। চলো দেখি কি হয় ????????????????
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = new Customer();
C2.FirstName = "Nayeem";
C2.LastName = "Shahriar";
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
}
}
কোডটি রান করে দেখো , কি আউটপুট আসে ??
এবার কি হলো ?? বলো তো দেখি ?? হুম আমাদের দুই ক্ষেত্রেই একই নাম ব্যবহার করেছি , তারপরো আমাদের এক দেখালো না !! এর কারণ , নিশ্চই বুঝতে পেরেছো ইতিমধ্যে ।। আমরা দুই দুইটা আলাদা আলাদা অব্জেক্ট ক্রিয়েট করেছি সাথে সাথে দুই দুইটা আলাদা আলাদা রেফারেন্স ভ্যারিয়েবল । যখন আমরা , আলাদা আলাদা ভ্যারিয়েবল চেক করাতে গেলাম , তখনই প্রথম ধাক্কাতে হেরে গেলাম , কারণ দুইটা ভ্যারিয়েবলই আলাদা আলাদা অব্জেক্টকে পয়েন্ট করছে ।। তাই সেখান থেকেই , ধরে নেয়া হয়েছে যে তারা সমান নয় , এই কারণে - আউটপুটে False পেয়েছি ।।
এখন এই সমস্যা থেকে বাচতে , আমাদের সাহায্য করবে আমাদের Equals() মেথোড ।। তার ডিফল্টভাবে যে ভারচুয়াল মেথোড আছে , তার উপরে আমরা ওভাররাইড করার সুযোগ আছে ,আমরা এখন এই সুযোগ ব্যবহার করবো ।।
using System;
using System.Collections.Generic;
namespace joy
{
public class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.FirstName = "Nayeem";
C1.LastName = "Shahriar";
Customer C2 = new Customer();
C2.FirstName = "Nayeem";
C2.LastName = "Shahriar";
Console.WriteLine(C2==C1);
Console.WriteLine(C2.Equals(C1));
Console.ReadKey();
}
}
public class Customer
{
public string FirstName { set; get; }
public string LastName { set; get; }
public override bool Equals(object obj)
{
if(obj==null)
{
return false;
}
if(!(obj is Customer))
{
return false;
}
return this.FirstName == ((Customer)obj).FirstName && this.LastName == ((Customer)obj).LastName;
}
public override int GetHashCode()
{
return this.FirstName.GetHashCode() ^ this.LastName.GetHashCode();
}
}
}
তো , আমরা ঠিকঠাকভাবেই সেই সুযোগ ব্যবহার করেছি ।। যদি , আমরা Equals মেথোদের মধ্যে object টাইপে যে পযারামিটার পাঠাবো , সেটা যদি নাল হয় , তাহলে রিটার্ন তো ভুল হবেই । আর , যদি আমাদের প্যারামিটার হয় অন্য কোনো ক্লাসের টাইপের !! তাহলে তো , কখনো ভিন্ন কোনো টাইপের জিনিস কম্পেয়ার করা হয় না , তাই ভুল হবে । [ !(obj is Customer) ]
আর তারপর নামগুলো সমান কি না ?? সেটা চেক করে , তারপর রিটারন করবো [ return this.FirstName == ((Customer)obj).FirstName && this.LastName == ((Customer)obj).LastName;]
আর আমাদের ওয়ারনিং এড়ানোর জন্য , আমরা যখন Equals মেথোডের ওভাররাইড করবো , তখন - GetHashCode() মেথোডেরও ওভাররাইড করবো , এই মেথোড এক ধরনের হ্যাশকোড প্রদান করে যা , সাধারণত এক ধরণের নিউমেরিক ভ্যালু যেটা একটা অব্জেক্ট এর আইডেনটিফেকিশেন হিসেবে কাজ করে , এর সাহায্যে আমরা - দুইটি অব্জেক্ট এর ইকুয়ালিটি চেক করতে পারি খুব এফিশিয়েন্ট ভাবে ।। দুইটা অব্জেক্ট সমান হলে তাদের হ্যাশকোডও সমান হয় , বাট দুইটা হ্যাশকোড সমান হলেই যে সেই অব্জেক্ট দুটো সমান হবে , তা কিন্তু নয় !! দুইটা অসমান অব্জেক্ট এরও হ্যাশকোড সমান হতে পারে !!!
আসলে , আমরা যখন এই ইকুয়াল মেথোড কল করে , দুইটা অব্জেক্ট এর ইকুয়ালিটি চেক করি তখন অটোমেটিকভাবেই .GetHashCode মেথোড কল করে , হ্যাশ কোড বের করে চেক করে , তাই আমরা
ইকুয়াল মেথোড ইউজ করলে , সাথে সাথে GetHashCode() মেথোডও অভাররাইড করে দেবো , যদিও আপাতভাবে আমাদের কাছে , এই মেথোড এর কোনো কাজ নেই ।।
এই বিষয়ে পরবরতিতে বিস্তারিত কথা বলবো ,
আজ কে আর নয় -----------------------
No comments:
Post a Comment