আইক্যায়েটেবল এবং কেবল ওভাররাইডিং অবজেক্ট.একুয়ালস () এর মধ্যে পার্থক্য কী?


183

আমি চাই আমার Foodক্লাস যখনই এটির অন্য উদাহরণগুলির সাথে সমান হয় তখন পরীক্ষা করতে সক্ষম হয় Food। আমি পরে এটি কোনও তালিকার বিরুদ্ধে ব্যবহার করব এবং আমি এর List.Contains()পদ্ধতিটি ব্যবহার করতে চাই । আমার কি বাস্তবায়ন করা উচিত IEquatable<Food>বা কেবল ওভাররাইড করা উচিত Object.Equals()? এমএসডিএন থেকে:

এই পদ্ধতিটি আইকুইটিটেবলের আইটেমের প্রয়োগের দ্বারা সংজ্ঞায়িত হিসাবে ডিফল্ট সমতা তুলনামূলককে ব্যবহার করে সমতা নির্ধারণ করে T টি (তালিকার মানগুলির ধরণ) এর জন্য পদ্ধতি পদ্ধতি।

সুতরাং আমার পরবর্তী প্রশ্নটি: .NET কাঠামোর কোন ফাংশন / শ্রেণি ব্যবহার করে Object.Equals()? আমি এটি প্রথম জায়গায় ব্যবহার করা উচিত?


3
খুব ভাল ব্যাখ্যা এখানে ব্লগস.এমএসডিএন
বি /

উত্তর:


213

মূল কারণটি হচ্ছে পারফরম্যান্স। যখন জেনেরিক্স .NET 2.0 ব্যবস্থা চালু হয়েছে তারা যেমন ঝরঝরে শ্রেণীর একটি গুচ্ছ যোগ করতে সক্ষম হয়েছি List<T>, Dictionary<K,V>, HashSet<T>, ইত্যাদি এই স্ট্রাকচার ভারী ব্যবহার করতে GetHashCodeএবং Equals। তবে মান ধরণের জন্য প্রয়োজনীয় বক্সিং। IEquatable<T>কোনও কাঠামোর দৃ strongly়ভাবে টাইপ করা Equalsপদ্ধতি কার্যকর করতে দেয় যাতে কোনও বক্সিং প্রয়োজন হয় না। জেনেরিক সংগ্রহের সাথে মান ধরণের ব্যবহার করার সময় এইরকম আরও ভাল পারফরমেন্স।

রেফারেন্সের ধরণেরগুলি তেমন সুবিধা IEquatable<T>দেয় না তবে বাস্তবায়ন আপনাকে এমন একটি কাস্ট এড়াতে দেয় System.Objectযা থেকে প্রায়শই বলা হয়ে থাকলে কোনও পার্থক্য তৈরি করতে পারে।

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


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

7
এটি সি ++ তে সত্য তবে নেট নেটওয়ার্কগুলি নয় যা ধরণের সুরক্ষা প্রয়োগ করে। একটি রানটাইম কাস্ট রয়েছে এবং যদি কাস্ট সফল না হয় তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে। কাস্টিংয়ের জন্য অর্থ প্রদানের জন্য একটি ছোট রানটাইম জরিমানা রয়েছে। সংকলক আপকাস্টগুলি অপ্টিমাইজ করতে পারে উদাহরণস্বরূপ অবজেক্ট ও = (অবজেক্ট) "স্ট্রিং"; তবে ডাউন কাস্টিং - স্ট্রিং এস = (স্ট্রিং) ও; - রানটাইমে অবশ্যই ঘটবে।
জোশ

1
আমি দেখি. সুযোগমতো আপনার কোনও জায়গা রয়েছে যেখানে আমি। নেট সম্পর্কে "ধরণের" গভীর তথ্য পেতে পারি? ধন্যবাদ!
ইলিজিয়াম

7
আমি জেফ রিখর দ্বারা সি # এর মাধ্যমে সিএলআর এবং জোন স্কিটের গভীরতায় সি # এর পরামর্শ দেব। ব্লগ হিসাবে, Wintellect ব্লগ ভাল, MSDN ব্লগ, ইত্যাদি হয়
জোশ

না IEquatable<T>চেয়ে ইন্টারফেস Do আর কিছু একজন বিকাশকারী মনে করিয়ে একটি অন্তর্ভুক্ত করা public bool Equals(T other) বর্গ বা struct অনেক সদস্য? ইন্টারফেসের উপস্থিতি বা অনুপস্থিতি রান-টাইমে কোনও পার্থক্য করে না। এর ওভারলোডটি Equalsসমস্ত প্রয়োজনীয় মনে হয়।
মাইকমে

47

এমএসডিএন অনুসারে :

যদি আপনি বাস্তবায়ন করেন তবে আপনার IEquatable<T>বেস শ্রেণীর প্রয়োগগুলিও ওভাররাইড করা উচিত Object.Equals(Object)এবং GetHashCode যাতে তাদের আচরণ IEquatable<T>.Equals পদ্ধতিটির সাথে সামঞ্জস্য হয় । আপনি যদি ওভাররাইড করেন তবে Object.Equals(Object)আপনার ওভাররাইড বাস্তবায়ন Equals(System.Object, System.Object)আপনার ক্লাসের স্থির পদ্ধতিতে কলগুলিতে ডাকা হবে । এটি নিশ্চিত করে যে Equalsপদ্ধতির সমস্ত অনুরোধগুলি ধারাবাহিক ফলাফল প্রত্যাবর্তন করে।

সুতরাং দেখে মনে হচ্ছে যে ক্লাসটি কীভাবে ব্যবহৃত হবে তার উপর নির্ভর করে বলা যেতে পারে যে ব্যতীত দুজনের মধ্যে কোনও বাস্তব কার্যকরী পার্থক্য নেই। পারফরম্যান্সের দিক থেকে জেনেরিক সংস্করণটি ব্যবহার করা আরও ভাল কারণ এর সাথে কোনও বক্সিং / আনবক্সিং পেনাল্টি নেই।

যৌক্তিক দৃষ্টিকোণ থেকে ইন্টারফেসটি প্রয়োগ করা আরও ভাল। বস্তুকে ওভাররাইড করা সত্যিই কাউকে বলতে পারে না যে আপনার শ্রেণিটি আসলে সমতুল্য। ওভাররাইডটি কেবল একটি করণীয় ক্লাস বা অগভীর বাস্তবায়ন হতে পারে। ইন্টারফেসটি স্পষ্টভাবে ব্যবহার করে বলে, "আরে, এই জিনিসটি সমতা পরীক্ষার জন্য বৈধ!" এটি ঠিক আরও ভাল নকশা।


9
স্ট্রাক্টসগুলি অবশ্যই অভিধানে বা অনুরূপ সংগ্রহের কী হিসাবে ব্যবহার করতে চলেছে যদি তাদের আইকুয়েটেবল (তাদের নিজস্ব টাইপ) বাস্তবায়িত করা উচিত; এটি একটি বড় কর্মক্ষমতা বৃদ্ধির প্রস্তাব করবে offer অ-উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাসগুলি আইকুয়েটেবল (তাদের নিজস্ব টাইপ) প্রয়োগ করে সামান্য পারফরম্যান্স উত্সাহ পাবেন। উত্তরাধিকারী শ্রেণিগুলিকে // নয় // আইকুইটেবল প্রয়োগ করা উচিত।
সুপারক্যাট

30

ব্যবহারিক উদাহরণ দিয়ে জোশ যা বললেন তা প্রসারিত করা। জোশের কাছে +1 - আমি আমার উত্তরে একই লিখতে চলেছিলাম।

public abstract class EntityBase : IEquatable<EntityBase>
{
    public EntityBase() { }

    #region IEquatable<EntityBase> Members

    public bool Equals(EntityBase other)
    {
        //Generic implementation of equality using reflection on derived class instance.
        return true;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as EntityBase);
    }

    #endregion
}

public class Author : EntityBase
{
    public Author() { }
}

public class Book : EntityBase
{
    public Book() { }
}

এইভাবে, আমার কাছে পুনরায় ব্যবহারযোগ্য ইক্যুয়ালগুলি () পদ্ধতি রয়েছে যা আমার সমস্ত উত্পন্ন শ্রেণীর জন্য বাক্সের বাইরে কাজ করে।


আরও একটি প্রশ্ন। (এনটিটিবেস) আপত্তিটির পরিবর্তে "এজেন্টটি এন্টিবেস হিসাবে" ব্যবহার করে কী লাভ? শুধু স্টাইলের বিষয় নাকি আদৌ কোনও সুবিধা আছে?
গ্রাস করে খেয়েছে ly

22
"এনটিটিবেজ হিসাবে আপত্তি" এর ক্ষেত্রে - যদি আপত্তিটি এন্টিবেস টাইপের না হয় তবে এটি "নাল" পাস করবে এবং কোনও ত্রুটি বা ব্যতিক্রম ছাড়াই চলতে থাকবে, তবে "(এনটিটিবেজ) আপত্তি" এর ক্ষেত্রে এটি জোর করে আপত্তিটি চেষ্টা করার চেষ্টা করবে এন্টিবেসে এবং যদি আপত্তিটি ইন্টিটিবেস টাইপের না হয় তবে এটি অকার্যকাস্টএক্সসেপশন নিক্ষেপ করবে। এবং হ্যাঁ, "হিসাবে" কেবলমাত্র রেফারেন্স ধরণের ক্ষেত্রে প্রয়োগ করা যেতে পারে।
এই __curious_geek

1
জ্যারেড পারের ব্লগে জোশের লিঙ্কটি মনে হয় আপনাকে গেটহ্যাশকোডকে ওভাররাইড করতে হবে। এটা কি না?
এপিসেবল

3
আপনার বাস্তবায়ন যে অতিরিক্ত মূল্য দেয় তা আমি সত্যিই পাই না। আপনার বিমূর্ত বেস শ্রেণি যে সমস্যার সমাধান করে তা আপনি কি পরিষ্কার করতে পারেন?
Mert আক্কায়া

1
@ অ্যাকবেবল - হ্যাঁ, আপনি যখনই অবজেক্ট.একুয়ালস (অবজেক্ট) কে ওভাররাইড করবেন তখন আপনার অবশ্যই গেটহ্যাশকোডকে ওভাররাইড করতে হবে যাতে পাত্রে কাজ হয়।
নামফোর্ড

0

আমরা যদি কল করি তবে object.Equalsএটি মূল্য ধরণের দামের বক্সিংয়ে বাধ্য হয়। কর্মক্ষমতা-সংবেদনশীল পরিস্থিতিতে এটি অনাকাঙ্ক্ষিত। সমাধানটি ব্যবহার করা হয় IEquatable<T>

public interface IEquatable<T>
{
  bool Equals (T other);
}

পিছনে ধারণাটি IEquatable<T>হ'ল এটি একই ফলাফল দেয় object.Equalsতবে আরও দ্রুত। সীমাবদ্ধতা where T : IEquatable<T>নীচের মত জেনেরিক ধরণের সাথে অবশ্যই ব্যবহার করা উচিত।

public class Test<T> where T : IEquatable<T>
{
  public bool IsEqual (T a, T b)
  {
    return a.Equals (b); // No boxing with generic T
  }
}

অন্যথায়, এটি আবদ্ধ slower object.Equals()

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