আইক্যুয়ালিটি কম্পিউটার <টি> এবং আইকোয়াটেবল <টি> এর মধ্যে পার্থক্য কী?


151

কোথায় IEqualityComparer<T>এবং কোথায় IEquatable<T>ব্যবহার করা উচিত তা আমি বুঝতে চাই । উভয়ের জন্য এমএসডিএন ডকুমেন্টেশন দেখতে খুব সাদৃশ্যপূর্ণ।


1
এমএসডিএন সেজ: "এই ইন্টারফেসটি সংগ্রহের জন্য কাস্টমাইজড সমতা তুলনা বাস্তবায়নের অনুমতি দেয় " "অবশ্যই নির্বাচিত উত্তরে অনুমান করা হয়। এমএসডিএন EqualityComparer<T>ইন্টারফেস বাস্তবায়নের পরিবর্তে উত্তরাধিকার EqualityComparer<T>IEquatable<T>
সূত্রেও

... উপরের পরামর্শ দেয় যে কোনও Tবাস্তবায়ন করার জন্য আমার একটি কাস্টম সংগ্রহ তৈরি করা উচিত IEquatable<T>List<T>অন্যথায় কি কোনও সংগ্রহের মতো সূক্ষ্ম বাগ থাকতে পারে?
রডারবব


@ রমিল শাভালিদেভ লিঙ্কটি নষ্ট হয়েছে
চেসম্যাক্স

উত্তর:


117

IEqualityComparer<T>একটি বস্তু যে ধরনের দুটি বস্তুর উপর তুলনা সঞ্চালিত একটি ইন্টারফেস T

IEquatable<T>এটি টাইপের কোনও অবজেক্টের জন্য Tযাতে এটি একই ধরণের অন্যটির সাথে নিজেকে তুলনা করতে পারে।


1
একই পার্থক্য হ'ল আইকোম্যাপারেবল / আইকোপ্যামার
বক্টুলাস

3
ক্যাপ্টেন স্পষ্ট
স্টেপান ইভানেনকো

(সম্পাদিত) IEqualityComparer<T>একটি অবজেক্টের জন্য ইন্টারফেস (যা সাধারণত একটি হালকা ওজনের শ্রেণীর চেয়ে আলাদা হয় T) যা তুলনামূলক ফাংশনগুলি সরবরাহ করে যা চালিত হয়T
rwong

61

যখন সিদ্ধান্ত নেওয়ার সময় ব্যবহার করার জন্য IEquatable<T>বা IEqualityComparer<T>, এক জিজ্ঞেস করতে পারি:

Tসাম্যের জন্য দুটি দৃষ্টান্ত পরীক্ষা করার কোনও পছন্দনীয় উপায় আছে , বা বেশ কয়েকটি সমানভাবে বৈধ উপায় আছে কি?

  • Tসাম্যতার জন্য দুটি উদাহরণ পরীক্ষা করার যদি কেবল একটি উপায় থাকে, বা যদি কয়েকটি পদ্ধতির মধ্যে একটি পছন্দ হয় IEquatable<T>তবে সঠিক পছন্দ হবে: এই ইন্টারফেসটি কেবল Tনিজেই প্রয়োগ করা হবে বলে মনে করা হয়, যাতে একটি উদাহরণের Tঅভ্যন্তরীণ জ্ঞান থাকে কীভাবে নিজেকে অন্য একটি উদাহরণের সাথে তুলনা করতে হয় T

  • অন্যদিকে, Tসমতার জন্য দু'জনের তুলনা করার জন্য যদি বেশ কয়েকটি সমান যুক্তিসঙ্গত পদ্ধতি থাকে IEqualityComparer<T>তবে এটি আরও উপযুক্ত বলে মনে হয়: এই ইন্টারফেসটি Tনিজের দ্বারা প্রয়োগ করা নয়, বরং অন্যান্য "বাহ্যিক" শ্রেণীর দ্বারা বোঝানো হচ্ছে । সুতরাং, Tসাম্যতার জন্য দুটি উদাহরণ পরীক্ষা করার সময় , কারণ সাম্যের Tকোনও অভ্যন্তরীণ উপলব্ধি নেই, আপনাকে অবশ্যই একটি IEqualityComparer<T>উদাহরণের একটি স্পষ্ট পছন্দ করতে হবে যা আপনার নির্দিষ্ট প্রয়োজনীয়তা অনুসারে পরীক্ষাটি সম্পাদন করে।

উদাহরণ:

আসুন এই দুটি ধরণের বিবেচনা করা যাক (যার মান শব্দার্থবিজ্ঞান রয়েছে বলে মনে করা হয় ):

interface IIntPoint : IEquatable<IIntPoint>
{
    int X { get; }
    int Y { get; }
}

interface IDoublePoint  // does not inherit IEquatable<IDoublePoint>; see below.
{
    double X { get; }
    double Y { get; }
}

কেন এই ধরণের একেরই উত্তরাধিকারী হবে IEquatable<>তবে অন্যটি নয়?

তত্ত্বের ক্ষেত্রে, উভয় প্রকারের দুটি উদাহরণের সাথে তুলনা করার একটি মাত্র বোধগম্য উপায় রয়েছে: উভয় দৃষ্টান্তে Xএবং Yবৈশিষ্ট্য সমান হলে সেগুলি সমান। এই চিন্তাভাবনা অনুসারে, উভয় প্রকারেরই প্রয়োগ করা উচিত IEquatable<>, কারণ সমতা পরীক্ষা করার অন্যান্য অর্থবহ উপায় আছে বলে মনে হয় না।

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

sealed class DoublePointNearEqualityComparerByTolerance : IEqualityComparer<IDoublePoint>
{
    public DoublePointNearEqualityComparerByTolerance(double tolerance) {  }
    
    public bool Equals(IDoublePoint a, IDoublePoint b)
    {
        return Math.Abs(a.X - b.X) <= tolerance  &&  Math.Abs(a.Y - b.Y) <= tolerance;
    }
    
}

নোট করুন যে পৃষ্ঠায় আমি লিঙ্ক করেছি (উপরে) স্পষ্টভাবে বলেছে যে কাছাকাছি-সমতার জন্য এই পরীক্ষার কিছু দুর্বলতা রয়েছে। যেহেতু এটি একটি IEqualityComparer<T>বাস্তবায়ন, এটি আপনার উদ্দেশ্যগুলির পক্ষে যথেষ্ট ভাল না হলে আপনি কেবল এটিকে সরিয়ে নিতে পারেন।


6
ডবল দফা সমতা পরীক্ষার জন্য প্রস্তাব তুলনা পদ্ধতি নষ্ট হয়ে গেছে, যেহেতু কোনো বৈধ IEqualityComparer<T>বাস্তবায়ন আবশ্যক একটি সমানতা সম্পর্ক, যা যে বোঝা বাস্তবায়ন সব ক্ষেত্রে যেখানে দুটি বস্তুর এক তৃতীয়াংশ সমান তুলনা, তারা অবশ্যই একে অপরের সমান তুলনা করুন। উপরোক্তির বিপরীতে প্রয়োগ করা IEquatable<T>বা IEqualityComparer<T>ফ্যাশনে প্রয়োগ করা কোনও শ্রেণি ভাঙা।
সুপারক্যাট

5
একটি ভাল উদাহরণ স্ট্রিং মধ্যে তুলনা করা হবে। স্ট্রিং তুলনা পদ্ধতিটি বোধগম্য হয় যা স্ট্রিংগুলিকে কেবল সমান হিসাবে বিবেচনা করে যদি সেগুলিতে বাইটগুলির একই ক্রম থাকে তবে অন্যান্য দরকারী তুলনা পদ্ধতি রয়েছে যা সমতা সংক্রান্ত সম্পর্ক যেমন কেস-সংবেদনশীল তুলনাও গঠন করে। মনে রাখবেন যে IEqualityComparer<String>"হ্যালো" এবং "এইচলো" উভয়ের সমান হিসাবে "হ্যালো" হিসাবে বিবেচিত একটিকে অবশ্যই "হ্যালো" এবং "এইচএললো" একে অপরের সমান বিবেচনা করতে হবে, তবে বেশিরভাগ তুলনামূলক পদ্ধতির জন্য যা কোনও সমস্যা হবে না।
সুপারক্যাট

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

এটি ঠিক আমার প্রয়োজন এবং আমি কী করছি। তবে গেটহ্যাশকোডকে ওভাররাইড করার দরকার আছে, মানগুলি পৃথক হয়ে গেলে এটি মিথ্যা ফিরে আসবে। আপনি কীভাবে আপনার গেটহ্যাশকোড পরিচালনা করবেন?
টিপেনগ করুন

@teapeng: আপনি কোন নির্দিষ্ট ব্যবহারের ক্ষেত্রে কথা বলছেন তা নিশ্চিত নয়। সাধারণভাবে বলতে গেলে, GetHashCodeদুটি মান পৃথক কিনা তা আপনাকে দ্রুত নির্ধারণ করার অনুমতি দেওয়া উচিত। নিয়মগুলি মোটামুটি নিম্নরূপ: (1) GetHashCode সর্বদা একই মানের জন্য একই হ্যাশ কোড তৈরি করতে হবে। (২) GetHashCode দ্রুত হওয়া উচিত (এর চেয়ে দ্রুত Equals)। (3) GetHashCode নির্ভুল হতে হবে না (হিসাবে সুনির্দিষ্ট না Equals)। এর অর্থ এটি বিভিন্ন মানের জন্য একই হ্যাশ কোড তৈরি করতে পারে। আপনি এটি আরও সুনির্দিষ্টভাবে তৈরি করতে পারেন, তত ভাল, তবে এটি দ্রুত রাখা আরও সম্ভবত গুরুত্বপূর্ণ।
স্টাকেক্স - 11

27

তারা কী সেটির প্রাথমিক সংজ্ঞা আপনি ইতিমধ্যে পেয়েছেন । সংক্ষেপে বলতে গেলে, আপনি যদি বাস্তবায়ন IEquatable<T>বর্গ উপর T, Equalsপ্রকারের একটি বস্তু উপর পদ্ধতি Tআপনি বলে যদি বস্তুর নিজেই (এক সমতার জন্য পরীক্ষা করা হচ্ছে) একই ধরণের আরেকটি দৃষ্টান্ত সমান T। যেখানে সাধারণত IEqualityComparer<T>দুটি উদাহরণের ক্ষেত্রের Tবাইরে যে কোনও দুটি উদাহরণের সাম্যতা পরীক্ষা করার জন্য T

হিসেবে তারা কি জন্য প্রথমে বিভ্রান্তিকর হতে পারে। সংজ্ঞা থেকে এটি স্পষ্ট হওয়া উচিত যে অতএব IEquatable<T>(শ্রেণিতে Tনিজেই সংজ্ঞায়িত ) এর বিষয়গুলি / উদাহরণগুলির স্বতন্ত্রতা উপস্থাপনের জন্য ডি-ফ্যাক্টো স্ট্যান্ডার্ড হওয়া উচিত। HashSet<T>, Dictionary<T, U>(বিবেচনা GetHashCodeকরা পাশাপাশি ওভাররাইড করা হয়), ইত্যাদি ব্যবহার Containsকরুন List<T>make বাস্তবায়নকারী IEqualityComparer<T>উপর Tউপরে উল্লিখিত সাধারণ ক্ষেত্রে সাহায্য করে না। পরবর্তীতে, ব্যতীত IEquatable<T>অন্য কোনও শ্রেণিতে প্রয়োগের জন্য খুব কম মূল্য রয়েছে T। এই:

class MyClass : IEquatable<T>

খুব কমই বোঝা যায়।

অন্য দিকে

class T : IEquatable<T>
{
    //override ==, !=, GetHashCode and non generic Equals as well

    public bool Equals(T other)
    {
        //....
    }
}

এটি করা উচিত কিভাবে।

IEqualityComparer<T>সাম্যতার একটি কাস্টম বৈধতা প্রয়োজন হলে কার্যকর হতে পারে, তবে সাধারণ নিয়ম হিসাবে নয়। উদাহরণস্বরূপ, কোনও এক শ্রেণিতে Personআপনার বয়সের উপর ভিত্তি করে দুটি ব্যক্তির সমতা পরীক্ষা করতে হতে পারে। সেক্ষেত্রে আপনি করতে পারেন:

class Person
{
    public int Age;
}

class AgeEqualityTester : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.Age == y.Age;
    }

    public int GetHashCode(Person obj)
    {
        return obj.Age.GetHashCode;
    }
}

তাদের পরীক্ষা করার জন্য, চেষ্টা করুন

var people = new Person[] { new Person { age = 23 } };
Person p = new Person() { age = 23 };

print people.Contains(p); //false;
print people.Contains(p, new AgeEqualityTester()); //true

একইভাবে IEqualityComparer<T>উপর Tঅর্থে দেখা যায় না।

class Person : IEqualityComparer<Person>

সত্য এটি কাজ করে তবে চোখের কাছে ভাল লাগে না এবং যুক্তিটিকে পরাভূত করে।

সাধারণত আপনার যা প্রয়োজন তা হ'ল IEquatable<T>। এছাড়াও আদর্শভাবে আপনার কেবল একটি থাকতে পারে IEquatable<T>যখন IEqualityComparer<T>বিভিন্ন মানদণ্ডের ভিত্তিতে একাধিক সম্ভব possible

IEqualityComparer<T>এবং IEquatable<T>ঠিক অনুরূপ হয় Comparer<T>এবং IComparable<T>যা বরং equating চেয়ে তুলনা উদ্দেশ্যে ব্যবহার করা হয়; এখানে একটি ভাল থ্রেড যেখানে আমি একই উত্তর লিখেছি :)


public int GetHashCode(Person obj)ফিরে obj.GetHashCode()
আসা

@ হিস্টো ইয়ানকভের ফিরে আসা উচিত obj.Age.GetHashCode। সম্পাদনা করবে।
নওফাল

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

@ হিস্টো ইয়াঙ্কভ আপনার তুলনাকারী জানেন না যে ব্যক্তি কীভাবে তার হ্যাশ গণনা করে - অবশ্যই, এ কারণেই আমরা সরাসরি person.GetHashCodeকোথাও ফোন করিনি .... আপনি কেন এটিকে ওভাররাইড করবেন? - আমরা ওভাররাইড করি কারণ সম্পূর্ণ বিধিটি IEqualityComparerআমাদের বিধি অনুসারে আলাদা তুলনা বাস্তবায়ন করতে হয় - যে নিয়মগুলি আমরা সত্যিই ভাল জানি।
নওফাল

আমার উদাহরণে, আমার তুলনা Ageসম্পত্তি থেকে বন্ধ করা প্রয়োজন , তাই আমি কল করি Age.GetHashCode। বয়স প্রকারভেদ int, তবে টাইপ যাই হ'ল হ্যাশ কোড চুক্তি .NET এ different objects can have equal hash but equal objects cant ever have different hashes। এটি এমন একটি চুক্তি যা আমরা অন্ধভাবে বিশ্বাস করতে পারি। নিশ্চিত যে আমাদের কাস্টম তুলনাকারীদেরও এই নিয়মটি মেনে চলতে হবে। যদি কখনও কলিং someObject.GetHashCodeজিনিসগুলি বিরতি দেয়, তবে এটি প্রকারের প্রয়োগকারীদের ক্ষেত্রে সমস্যা someObjectএটি আমাদের সমস্যা নয়।
নওফাল

11

আইক্যুয়্যালিসিম্পারার ব্যবহারের জন্য যখন দুটি বস্তুর সাম্যতা বাহ্যিকভাবে প্রয়োগ করা হয়, যেমন আপনি যদি দুটি সংখ্যার জন্য কোনও উত্সকারকের সংজ্ঞা দিতে চান যেটির উত্স আপনার নেই, বা এমন ক্ষেত্রে যেখানে দুটি জিনিসের মধ্যে সাম্যতা কিছু সীমিত প্রসঙ্গে বোঝায় sense

আইকুয়েটেবল হ'ল অবজেক্টটি নিজেই (সমতার সাথে তুলনা করা হচ্ছে) বাস্তবায়নের জন্য।


আপনিই কেবলমাত্র যিনি "প্লাগিং ইন ইক্যুয়ালিটি" (বাহ্যিক ব্যবহার) ইস্যুটি উত্থাপন করেছিলেন। প্লাস 1.
রই নমির

4

এক দুটি Tএস তুলনা করে । অন্য নিজেকে অন্য Tএস এর সাথে তুলনা করতে পারে । সাধারণত, আপনার কেবল একবারে একটি ব্যবহার করা দরকার, দুটোই নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.