(অবজেক্ট) 0 == (অবজেক্ট) 0 ((অবজেক্ট) 0) থেকে আলাদা কেন? সমান ((অবজেক্ট) 0)?


117

নীচের এক্সপ্রেশনগুলি পৃথক কেন?

[1]  (object)0 == (object)0 //false
[2]  ((object)0).Equals((object)0) // true

প্রকৃতপক্ষে, আমি সম্পূর্ণরূপে বুঝতে পারি [1] কারণ সম্ভবত। নেট রানটাইম boxপূর্ণসংখ্যা এবং পরিবর্তে রেফারেন্সগুলির সাথে তুলনা শুরু করবে । তবে [২] কেন আলাদা?


36
ঠিক আছে, এখন আপনি এই প্রশ্নের উত্তর বুঝতে পেরেছেন, এর ফলাফল সম্পর্কে ভবিষ্যদ্বাণী করে আপনার বোধগম্যতা পরীক্ষা করুন: short myShort = 0; int myInt = 0; Console.WriteLine("{0}{1}{2}", myShort.Equals(myInt), myInt.Equals(myShort), myInt == myShort); এখন এটি বাস্তবতার বিপরীতে দেখুন। আপনার ভবিষ্যদ্বাণী সঠিক ছিল? যদি তা না হয় তবে পার্থক্য ব্যাখ্যা করতে পারবেন?
— এরিক লিপার্ট

1
@Star, প্রস্তাবিত পড়ার জন্য দেখতে msdn.microsoft.com/en-us/library/vstudio/... উপলব্ধ overloads জন্য int16ওরফে shortসমান পদ্ধতি, তারপর তাকান msdn.microsoft.com/en-us/library/ms173105.aspx । আমি এরিক লিপার্টের ধাঁধাটি নষ্ট করতে চাই না, তবে এই পৃষ্ঠাগুলি একবার পড়লে এটি নির্ধারণ করা খুব সহজ হওয়া উচিত।
— স্যাম স্কুচ

2
আমি ভেবেছিলাম এটি একটি জাভা প্রশ্ন; কমপক্ষে সমানতে 'ই' দেখার আগে।
— seteropere

4
@ সেটারোপেয়ার জাভা আসলে পৃথক: জাভাতে অটোবক্সিং বস্তুগুলিকে ক্যাশে করে, তাই ((Integer)0)==((Integer)0)সত্যকে মূল্যায়ন করে।
— জুলাই

1
আপনি চেষ্টা করতে পারেন IFormattable x = 0; bool test = (object)x == (object)x;। স্ট্রাক্ট ইতিমধ্যে একটি বাক্সে থাকা অবস্থায় কোনও নতুন বক্সিং করা হয় না।
— জেপ্প স্টিগ নীলসন

উত্তর:


151

কলগুলি যেভাবে ভিন্ন আচরণ করে সেগুলি হ'ল তারা খুব ভিন্ন পদ্ধতির সাথে আবদ্ধ।

==কেস স্ট্যাটিক রেফারেন্স সমতা অপারেটর জুড়তে হবে। এখানে দুটি স্বতন্ত্র বক্সযুক্ত intমান তৈরি করা হয়েছে সুতরাং সেগুলি একই রেফারেন্স নয়।

দ্বিতীয় ক্ষেত্রে আপনি উদাহরণ পদ্ধতিতে আবদ্ধ হন Object.Equals। এটি ভার্চুয়াল পদ্ধতি যা ফিল্ড করে নিবে Int32.Equalsএবং এটি একটি বাক্স পূর্ণসংখ্যার জন্য পরীক্ষা করে। উভয় পূর্ণসংখ্যার মান 0 সুতরাং তারা সমান


==কেস কল না Object.ReferenceEquals। এটি কেবল ceqএকটি রেফারেন্স তুলনা সম্পাদনের জন্য আইএল নির্দেশিকা উত্পাদন করে ।
— স্যাম হারওল

8
@ 280Z28 এটি কি কেবল সংকলকটি ইনলাইন করে না?
— মার্কমনল

@ 280Z28 তাই? অনুরূপ কেসটি হ'ল তাদের বুলিয়ান T টুস্ট্রিং পদ্ধতিতে প্রকাশ্যে প্রকাশিত বুলিয়ান r ট্রুইস্ট্রিং এবং বুলিয়ান F ফ্যালস স্ট্রিংয়ের পরিবর্তে তার ফাংশনের অভ্যন্তরে হার্ডকডযুক্ত স্ট্রিং রয়েছে। এটি অপ্রাসঙ্গিক; ==মুল বক্তব্যটি হ'ল ReferenceEquals(অবজেক্টে, যাইহোক) একই জিনিসটি করে। অপ্রয়োজনীয় অভ্যন্তরীণ ফাংশনগুলি যাতে ব্যবহার করা যায় না - ব্যবহারযোগ্য ফাংশনগুলি এড়াতে এটি এমএসের পক্ষে কেবল অভ্যন্তরীণ অনুকূলকরণ।
— নায়ারগডস

6
সি # ল্যাঙ্গুয়েজ স্পেসিফিকেশন, অনুচ্ছেদ 10.১০. says বলছে: পূর্বনির্ধারিত রেফারেন্স ধরণের সাম্য অপারেটরগুলিbool operator ==(object x, object y); bool operator !=(object x, object y); হ'ল অপারেটরগুলি সমতা বা অ-সাম্যের জন্য দুটি রেফারেন্সের তুলনার ফলাফল প্রদান করে return System.Object.ReferenceEqualsফলাফল নির্ধারণের জন্য পদ্ধতিটি ব্যবহার করা হয় এমন কোনও প্রয়োজনীয়তা নয় । To @markmnl: না, সি # সংকলক ইনলাইন করে না, এটি এমন কিছু যা ঘিটার কখনও কখনও করে (তবে এই ক্ষেত্রে নয়)। সুতরাং 280Z28 সঠিকভাবে ReferenceEqualsপদ্ধতিটি ব্যবহৃত হয় না।
— জেপ্প স্টিগ নীলসন

@ জারেডপার: এটি আকর্ষণীয় যে অনুমানটি বলে যে, যেহেতু ভাষা আসলে আচরণ করে না। উপরে হিসাবে সংজ্ঞায়িত অপারেটর এবং ভেরিয়েবল দেওয়া Cat Whiskers; Dog Fido; IDog Fred;(অ-সংশ্লিষ্ট ইন্টারফেসের জন্য ICatএবং IDogএবং অ সংশ্লিষ্ট শ্রেণীর Cat:ICatএবং Dog:IDog), তুলনা Whiskers==Fidoএবং Whiskers==34আইনি (প্রথম একমাত্র সত্য হতে পারে যদি গোঁফ এবং Fido উভয় নাল ছিল হবে; দ্বিতীয় কখনোই সত্য হতে পারে )। আসলে, একটি সি # সংকলক উভয়ই প্রত্যাখ্যান করবে। সিল Whiskers==Fred;করা থাকলে নিষিদ্ধ করা হবে Cat, তবে তা না থাকলে অনুমতি দেওয়া হবে।
— 18:36 এ সুপারকেট সুপারক্যাট

26

আপনি যখন মান মান 0(বা অন্য কোনও মান ধরণের) কাস্ট করেন তখন objectমানটি বাক্স হয় । প্রতিটি কাস্ট objectএকটি আলাদা বাক্স তৈরি করে (অর্থাত্ একটি পৃথক বস্তুর উদাহরণ)। ==জন্য অপারেটর objectটাইপ সঞ্চালিত একটি রেফারেন্স তুলনা, তাই এটি মিথ্যা ফেরৎ যেহেতু বাম দিকে এবং ডান দিকে একই উদাহরণস্বরূপ নয়।

অন্যদিকে, আপনি যখন ব্যবহার করেন Equalsযা একটি ভার্চুয়াল পদ্ধতি, এটি প্রকৃত বাক্সযুক্ত প্রকারের প্রয়োগটি ব্যবহার করে, অর্থাত্ Int32.Equals, যা সত্য প্রত্যাবর্তন করে যেহেতু উভয় বস্তুর একই মান রয়েছে।


18

==অপারেটর স্ট্যাটিক হচ্ছে, ভার্চুয়াল নয়। এটি objectক্লাসটি সংজ্ঞায়িত করে এমন সঠিক কোডটি চালাবে (`অবজেক্টগুলির সংকলন টাইম ধরণের বস্তু), যা উভয় বস্তুর রানটাইম ধরণের নির্বিশেষে একটি রেফারেন্স তুলনা করবে।

Equalsপদ্ধতি একটি ভার্চুয়াল উদাহরণস্বরূপ পদ্ধতি। এটি objectক্লাসের কোড নয়, (প্রথম) অবজেক্টের প্রকৃত রান-টাইম ধরণের সংজ্ঞায়িত কোডটি চলবে । এই ক্ষেত্রে, অবজেক্টটি হ'ল একটি int, সুতরাং এটি একটি মান তুলনা সম্পাদন করবে, কারণ এটি intতার Equalsপদ্ধতির জন্য টাইপটি এটি নির্ধারণ করে ।


==টোকেন আসলে দুটি অপারেটর, যার মধ্যে একটি overloadable হয় এবং যার এক নয় প্রতিনিধিত্ব করে। দ্বিতীয় অপারেটরের আচরণ একটি ওভারলোড অন (অবজেক্ট, অবজেক্ট) এর থেকে খুব আলাদা।
— সুপারক্যাট

13

Equals()পদ্ধতি ভার্চুয়াল হয়।
অতএব, কলসাইটটি কাস্ট করা থাকলেও এটি সর্বদা কংক্রিট বাস্তবায়নকে কল করে object। intমান Equals()দ্বারা তুলনা করতে ওভাররাইড , যাতে আপনি মান তুলনা পেতে।


10

== ব্যবহার করুন: Object.ReferenceEquals

Object.Equals মান তুলনা করে।

object.ReferenceEqualsপদ্ধতি রেফারেন্স তুলনা করা হয়। আপনি যখন কোনও বস্তু বরাদ্দ করেন, আপনি মেমরির হিপটিতে থাকা অবজেক্টের ডেটা ছাড়াও একটি মান সম্বলিত একটি রেফারেন্স পাবেন।

object.Equalsপদ্ধতি বস্তুর বিষয়বস্তু তুলনা করা হয়। এটি প্রথমে রেফারেন্সগুলি সমান কিনা তা যাচাই করে। রেফারেন্সএকুয়ালস। তবে তারপরে এটি আরও সমতা পরীক্ষা করার জন্য উত্পন্ন সমান পদ্ধতিগুলিতে কল করে। এটা দেখ:

   System.Object a = new System.Object();
System.Object b = a;
System.Object.ReferenceEquals(a, b);  //returns true

যদিও এটি Object.ReferenceEqualsএমন একটি পদ্ধতির মতো আচরণ করে যা ==তার অপারেন্সগুলিতে সি # অপারেটর ব্যবহার করে , সি # রেফারেন্স-সাম্যতা অপারেটর অপারেটর (যা ==অপারেণ্ড প্রকারের জন্য উপস্থাপিত হয় যার জন্য কোনও ওভারলোড সংজ্ঞায়িত হয় না) কল করার পরিবর্তে একটি বিশেষ নির্দেশ ব্যবহার করে ReferenceEquals। এরপরে, Object.ReferenceEqualsঅপারেশনগুলি গ্রহণ করবে যা কেবল দু'টিই বাতিল হয়ে গেলে মেলাতে পারে এবং এমন অপারেশনগুলি গ্রহণ করবে যাগুলির সাথে টাইপ-জোর করা দরকার Objectএবং সম্ভবত কোনও কিছুর সাথে মেলে না, যদিও এর রেফারেন্স-সমতা সংস্করণটি এই ==ধরনের ব্যবহারগুলি সংকলন করতে অস্বীকার করবে ।
— সুপারক্যাট

9

সি # অপারেটরটি ==দুটি পৃথক অপারেটরকে উপস্থাপন করতে টোকেন ব্যবহার করে : একটি স্ট্যাটিক্যালি- ওভারলোডযোগ্য তুলনামূলক অপারেটর এবং একটি অ-ওভারলোডযোগ্য রেফারেন্স-তুলনা অপারেটর। এটি যখন ==টোকেনের মুখোমুখি হয় , এটি প্রথমে পরীক্ষা করে যে কোনও সমতা-পরীক্ষা ওভারলোড রয়েছে যা অপারেন্ড ধরণের ক্ষেত্রে প্রযোজ্য। যদি তা হয় তবে এটি ওভারলোডটি চালিয়ে যাবে। অন্যথায়, এটি পরীক্ষা করবে যে প্রকারগুলি রেফারেন্স-তুলনা অপারেটরের ক্ষেত্রে প্রযোজ্য কিনা। যদি তা হয় তবে এটি অপারেটরটি ব্যবহার করবে। অপারেটর ধরণের ক্ষেত্রে অপারেটর উভয়ই প্রযোজ্য না হলে সংকলন ব্যর্থ হবে।

কোড (Object)0না নিছক upCast একটি করে Int32করতে Object: Int32সমস্ত মান ধরনের মত, আসলে দুই ধরনের, যার মধ্যে একটি মান এবং (যেমন আক্ষরিক শূন্য হিসাবে) এর ওপর সংগ্রহ অবস্থানে বর্ণনা প্রতিনিধিত্ব করে, কিন্তু কিছু থেকে আহরণ করা নয়, এবং যার এক বর্ণনা গাদা বস্তু এবং থেকে প্রাপ্ত Object; যেহেতু কেবলমাত্র পরবর্তীকালের প্রকারটি আপকাস্ট হতে পারে, সংকলককে Objectঅবশ্যই পরবর্তী প্রকারের একটি নতুন হ্যাপ অবজেক্ট তৈরি করতে হবে। প্রতিটি অনুরোধ (Object)0একটি নতুন হিপ অবজেক্ট তৈরি করে, সুতরাং দুটি অপারেশন ==পৃথক পৃথক বস্তু হয়, যার প্রতিটি স্বতন্ত্রভাবে Int32মান 0 মানিয়ে যায় ।

বর্গ Objectকোন ব্যবহারযোগ্য overloads সমান অপারেটর জন্য সংজ্ঞায়িত নেই। ফলস্বরূপ, সংকলক ওভারলোডেড সাম্যতা-পরীক্ষা অপারেটরটি ব্যবহার করতে সক্ষম হবে না এবং রেফারেন্স-সাম্যতা পরীক্ষা ব্যবহার করে ফিরে যাবে। যেহেতু দুটি অপারেশন ==পৃথক পৃথক অবজেক্টগুলি উল্লেখ করে, এটি প্রতিবেদন করবে false। দ্বিতীয় তুলনা সফল হয় কারণ এটি একটি হ্যাপ-অবজেক্টের উদাহরণটিকে অন্যটির Int32সমান কিনা তা জিজ্ঞাসা করে। কারণ এই উদাহরণটি অন্য একটি স্বতন্ত্র উদাহরণের সাথে সমান হওয়ার অর্থ কী তা জানে তাই এটি উত্তর দিতে পারে true।


তদতিরিক্ত, আপনি 0যখনই আপনার কোডটিতে আক্ষরিক লিখবেন ততবারই আমি ধরে নিয়েছি এটি এর জন্য গাদাতে একটি অন্তর্নির্মিত বস্তু তৈরি করে। এটি কোনও গ্লোবাল স্ট্যাটিক শূন্য মানের কোনও অনন্য রেফারেন্স নয় (যেমন তারা কীভাবে স্ট্রিং তৈরি করেছিল। নতুন খালি স্ট্রিং অবজেক্টগুলি কেবল নতুন স্ট্রিংয়ের সূচনা করার জন্য এড়ানোর জন্য এফটিটি) সুতরাং আমি নিশ্চিত যে এমনকি একটি করাও 0.ReferenceEquals(0)মিথ্যা প্রত্যাবর্তন করবে, যেহেতু উভয় 0 হ'ল নতুন নির্মিত Int32বস্তু
— নাইয়ারগডস

1
@ নাইয়ারগুডস, আমি পুরোপুরি নিশ্চিত যে আপনি বলেছেন সমস্ত কিছুই ভুল, ইনটস, হিপস, ইতিহাস, গ্লোবাল স্ট্যাটিকস ইত্যাদি সম্পর্কে 0.ReferenceEquals(0)ব্যর্থ হবে কারণ আপনি একটি সংকলনের সময় ধ্রুবকটিতে কোনও পদ্ধতি কল করার চেষ্টা করছেন। এটি বন্ধ করে দেওয়ার কোনও আপত্তি নেই। একটি আনবক্সড ইনট একটি স্ট্রাক্ট, স্ট্যাকের মধ্যে সঞ্চিত। এমনকি int i = 0; i.ReferenceEquals(...)কাজ করবে না। কারণ System.Int32উত্তরাধিকারসূত্রে প্রাপ্ত হয় না Object।
— অ্যান্ড্রু ব্যাকার

@AndrewBacker, System.Int32একটি হল struct, একটি structহল System.ValueTypeযা নিজেই উত্তরাধিকারী, System.Object। Thatswhy এর জন্য একটি ToString()পদ্ধতি এবং একটি Equalsপদ্ধতি রয়েছেSystem.Int32
— সেবাস্তিয়ান

1
তবুও, নায়ারগডস এই কথাটি বলা ভুল যে একটি গর্তের উপর একটি ইন্টার 32 তৈরি করা হবে, যা এটি নয়।
— সেবাস্তিয়ান

@ সেবাস্তিয়ানগোডলেট, আমি এতে অভ্যন্তরীনদের উপেক্ষা করছি। System.Int32 নিজেই এই পদ্ধতিগুলি প্রয়োগ করে। গেটটাইপ () চালু রয়েছে Objectএবং আমি দীর্ঘদিন আগে যেখানে এটির বিষয়ে চিন্তাভাবনা বন্ধ করে দিয়েছি। এর থেকে বেশি দূরে যাওয়ার দরকার ছিল না। আফাইক সিএলআর দুটি ধরণের আলাদা এবং বিশেষভাবে পরিচালনা করে। এটি কেবল উত্তরাধিকার নয়। এটা তোলে isযদিও ডাটা দুই ধরনের এক। আমি কেবল চাইনি যে কেউ এই মন্তব্যটি পড়ুক এবং এতদূর অবধি ট্র্যাক থেকে সরে যাক, খালি স্ট্রিংগুলি সম্পর্কে স্ট্রিং ইন্টার্নিং উপেক্ষা করে এমন অদ্ভুততা সহ।
— অ্যান্ড্রু ব্যাকার

3

দুটি চেকই আলাদা। প্রথমটি পরিচয়ের জন্য পরীক্ষা করে , দ্বিতীয়টি সাম্যের জন্য । সাধারণভাবে দুটি পদ অভিন্ন, যদি তারা একই বস্তুর প্রতি উল্লেখ করে থাকে। এগুলি বোঝায় যে তারা সমান। দুটি পদ সমান, যদি তাদের মান একই হয়।

প্রোগ্রামিং পরিচয়ের শর্তাবলী সাধারণত রেফারেন্স সাম্যতা দ্বারা জগাখিচুড়ি হয়। যদি উভয় পদগুলির পয়েন্টার সমান (!) হয় তবে তারা যে বস্তুটিতে পয়েন্ট করছে সেটি হুবহু একই। যাইহোক, যদি পয়েন্টারগুলি পৃথক হয় তবে তারা যে জিনিসগুলিতে পয়েন্ট করছে তার মান এখনও সমান হতে পারে। সি # পরিচয় স্থিতিশীল Object.ReferenceEqualsসদস্য ব্যবহার করে চেক করা যায়, অ স্থিতিশীল Object.Equalsসদস্য ব্যবহার করে সাম্যতা পরীক্ষা করা হয় । আপনি বস্তু দুটি পূর্ণসংখ্যার ভোটদান যেহেতু (যা "বক্সিং" বলা হয়, BTW), operatior ==এর objectসঞ্চালিত প্রথম চেক, যা ডিফল্টভাবে হয় ম্যাপ Object.ReferenceEqualsএবং পরিচয় চেক। আপনি যদি স্পষ্টতাই অ-স্থিতিশীল- Equalsমেম্বারকে কল করেন তবে গতিশীল প্রেরণের কলটিতে ফলাফল আসে Int32.Equals, যা সাম্যের জন্য পরীক্ষা করে।

উভয় ধারণা একই, কিন্তু এক নয়। এগুলি প্রথমে বিভ্রান্তিকর বলে মনে হতে পারে তবে ছোট পার্থক্যটি খুব গুরুত্বপূর্ণ! "অ্যালিস" এবং "বব" নামে দুটি ব্যক্তির কল্পনা করুন। তারা দু'জনই হলুদ ঘরে বাস করছেন। এই অনুমানের ভিত্তিতে, অ্যালিস এবং বব এমন একটি জেলায় বাস করছেন, যেখানে ঘরগুলি কেবল তাদের রঙের চেয়ে আলাদা, তারা উভয়ই বিভিন্ন হলুদ ঘরে থাকতে পারে। যদি আপনি উভয় বাড়ির তুলনা করেন তবে আপনি চিনতে পারবেন যে সেগুলি একেবারে সমান, কারণ তারা উভয়ই হলুদ! যাইহোক, তারা একই বাড়িতে ভাগ করে নিচ্ছে না এবং সুতরাং তাদের বাড়িগুলি সমান , তবে অভিন্ন নয় । পরিচয়টি বোঝায় যে তারা একই বাড়িতে বসবাস করছে ।

দ্রষ্টব্য : কিছু ভাষা ===পরিচয় পরীক্ষা করতে অপারেটরকে সংজ্ঞায়িত করছে ।

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