কেন আমাদের সি = এ == এবং! = উভয়ই সংজ্ঞায়িত করতে হবে?


346

সি # সংকলকটি আবশ্যক যে যখনই কোনও কাস্টম প্রকার অপারেটরকে সংজ্ঞায়িত করে ==, এটি অবশ্যই সংজ্ঞায়িত করতে হবে !=( এখানে দেখুন )।

কেন?

আমি জানতে আগ্রহী যে ডিজাইনাররা কেন এটি প্রয়োজনীয় বলে মনে করেছিল এবং কেবল অপর উপস্থিত হলে অপারেটরগুলির মধ্যে যে কোনও একটির পক্ষে যুক্তিসঙ্গত বাস্তবায়নের ক্ষেত্রে কেন সংকলকটি ডিফল্ট করতে পারে না। উদাহরণস্বরূপ, লুয়া আপনাকে কেবল সমতা অপারেটরটি সংজ্ঞায়িত করতে দেয় এবং আপনি অন্যটি বিনামূল্যে পান। সি # আপনাকে == বা উভয় == এবং! = সংজ্ঞা দিতে অনুরোধ করতে পারে এবং তারপরে স্বয়ংক্রিয়ভাবে নিখোঁজ! = অপারেটর হিসাবে সংকলন করতে পারে !(left == right)

আমি বুঝতে পারি যে এমন এক অদ্ভুত কোণার কেস রয়েছে যেখানে কিছু সত্ত্বা সমান বা অসম নাও হতে পারে (যেমন আইইইই-75৫৪ এনএএন), তবে এগুলি ব্যতিক্রম বলে মনে হয়, নিয়ম হিসাবে নয়। সুতরাং এটি কেন ব্যাখ্যা করে না যে সি # সংকলক ডিজাইনাররা কেন ব্যতিক্রমটিকে নিয়ম বানিয়েছেন।

আমি দুর্বল কারিগরতার ক্ষেত্রে দেখেছি যেখানে সাম্যতা অপারেটরটি সংজ্ঞায়িত করা হয়, তারপরে অসমতার অপারেটরটি প্রতিটি তুলনা উল্টে এবং অন & এ পরিবর্তন করে একটি অনুলিপি-পেস্ট হয় || (আপনি পয়েন্টটি পান ... মূলত! (a == খ) ডি মরগানের বিধি দ্বারা প্রসারিত)। এটি লুয়ার ক্ষেত্রে যেমন সংকলক ডিজাইন দ্বারা মুছে ফেলতে পারে এটি একটি খারাপ অনুশীলন।

দ্রষ্টব্য: অপারেটরদের <> <=> = এর জন্য এটি একই holds আপনি অপ্রাকৃত উপায়ে এগুলি সংজ্ঞায়িত করতে হবে এমন ক্ষেত্রে আমি কল্পনা করতে পারি না। লুয়া আপনাকে কেবল <এবং <= এবং সংজ্ঞায়িত> = এবং> ফর্মারদের প্রত্যাখ্যানের মাধ্যমে সংজ্ঞায়িত করতে দেয়। কেন সি # একই কাজ করে না (কমপক্ষে 'ডিফল্টরূপে')?

সম্পাদনা

স্পষ্টতই প্রোগ্রামারটি তাদের পছন্দ মতো সাম্যতা এবং বৈষম্যের জন্য চেক প্রয়োগ করতে অনুমতি দেওয়ার বৈধ কারণ রয়েছে। উত্তরগুলির কয়েকটি এমন ক্ষেত্রে নির্দেশ করে যেখানে এটি দুর্দান্ত হতে পারে।

আমার প্রশ্নের কার্নেল, তবে, কেন যখন জোর করে সি # তে এটি প্রয়োজনীয় হয় যখন সাধারণত এটি যুক্তিযুক্তভাবে প্রয়োজন হয় না ?

এটি নেট। ইন্টারফেসের মতো নকশার পছন্দগুলির বিপরীতেও রয়েছে Object.Equals, IEquatable.Equals IEqualityComparer.Equalsযেখানে একটি অংশের অভাব NotEqualsদেখায় যে কাঠামোটি !Equals()বস্তুগুলিকে অসম হিসাবে বিবেচনা করে এবং এটিই । তদুপরি, ক্লাসগুলির মতো Dictionaryএবং পদ্ধতিগুলি .Contains()কেবল পূর্বোক্ত ইন্টারফেসের উপর নির্ভর করে এবং অপারেটরগুলি সংজ্ঞায়িত হলেও সরাসরি ব্যবহার করে না। আসলে, যখন রিশার্পার সমতা সদস্য তৈরি করে, এটি উভয় ==এবং !=শর্তাদির এবং উভয়ই সংজ্ঞায়িত করে Equals()তবেই যদি ব্যবহারকারী মোটেই অপারেটর জেনারেট করতে পছন্দ করে। অবজেক্টের সাম্যতা বোঝার জন্য কাঠামোর দ্বারা সাম্যতা অপারেটরগুলির প্রয়োজন হয় না।

মূলত, .NET কাঠামো এই অপারেটরদের সম্পর্কে চিন্তা করে না, এটি কেবল কয়েকটি Equalsপদ্ধতি সম্পর্কে চিন্তা করে। ব্যবহারকারী দ্বারা মিলিয়ে == এবং! = অপারেটর উভয়কেই সংজ্ঞায়িত করার সিদ্ধান্ত নেওয়ার বিষয়টি ভাষা নকশার সাথে সম্পর্কিত এবং ড। সিএনটি সম্পর্কিত শব্দার্থবিজ্ঞানের সাথে সম্পর্কিত নয়।


24
একটি দুর্দান্ত প্রশ্নের জন্য +1। মোটেও কোনও কারণ বলে মনে হচ্ছে না ... অবশ্যই সংকলকটি ধরে নিতে পারে যে একটি! = বি অনুবাদ করা যেতে পারে! (A == খ) অন্যথায় না বললে। তারা কেন এই সিদ্ধান্ত নিয়েছে তা জানতে আগ্রহী cur
প্যাট্রিক 87

16
এটি আমি সবচেয়ে দ্রুত দেখেছি যে কোনও প্রশ্ন ভোট দিয়েছে এবং পছন্দসই হয়েছে।
ক্রিস্টোফার কারেনস

26
আমি নিশ্চিত যে @ এরিক লিপার্ট একটি ভাল উত্তরও সরবরাহ করতে পারে।
ইয়াক

17
"বিজ্ঞানী এমন ব্যক্তি নন যা সঠিক উত্তর দেয়, তিনিই সঠিক প্রশ্ন জিজ্ঞাসা করেন"। এ কারণেই এসইতে প্রশ্ন উত্সাহিত হয়। এবং এটি কাজ করে!
অ্যাড্রিয়ানো কার্নেইরো

4
পাইথনের জন্য একই প্রশ্ন: স্ট্যাকওভারফ্লো.com
জোশ লি

উত্তর:


161

আমি ভাষা ডিজাইনারদের পক্ষে কথা বলতে পারি না, তবে আমি যা যুক্তি করতে পারি তা থেকে মনে হয় এটি ইচ্ছাকৃত, সঠিক নকশার সিদ্ধান্ত ছিল।

এই বেসিক এফ # কোডটি দেখে আপনি এটি একটি কার্যকারী লাইব্রেরিতে সংকলন করতে পারেন। এটি F # এর জন্য আইনী কোড এবং বৈষম্য নয়, কেবল সাম্য অপারেটরকে ওভারলোড করে:

module Module1

type Foo() =
    let mutable myInternalValue = 0
    member this.Prop
        with get () = myInternalValue
        and set (value) = myInternalValue <- value

    static member op_Equality (left : Foo, right : Foo) = left.Prop = right.Prop
    //static member op_Inequality (left : Foo, right : Foo) = left.Prop <> right.Prop

এটি দেখতে যেমন দেখাচ্ছে ঠিক তেমন করে। এটি ==কেবলমাত্র একটি সমতা তুলক তৈরি করে এবং শ্রেণীর অভ্যন্তরীণ মান সমান কিনা তা পরীক্ষা করে।

আপনি সি # তে এর মতো ক্লাস তৈরি করতে পারবেন না, আপনি । নেট জন্য সংকলিত একটি ব্যবহার করতে পারেন। এটি স্পষ্টতই এটির জন্য আমাদের ওভারলোডেড অপারেটরটি ব্যবহার করবে == তাই রানটাইম কীসের জন্য ব্যবহার করবে !=?

সি # ইএমসিএ স্ট্যান্ডার্ডের পুরো বিচ্ছিন্ন বিধি রয়েছে (ধারা 14.9) যা সাম্যতার মূল্যায়ন করার সময় কোন অপারেটরটি ব্যবহার করতে হবে তা নির্ধারণ করে expla এটিকে অতি-সরলকরণ এবং পুরোপুরি নির্ভুলভাবে না রাখতে, তুলনা করা প্রকারগুলি একই ধরণের হয় এবং সেখানে একটি ওভারলোডেড সাম্যতা অপারেটর উপস্থিত থাকে, তবে এটি ওভারলোড ব্যবহার করবে এবং অবজেক্ট থেকে উত্তরাধিকার সূত্রে প্রাপ্ত আদর্শ রেফারেন্স সমতা অপারেটরটি নয়। তবে এতে অবাক হওয়ার কিছু নেই যে কেবলমাত্র অপারেটরগুলির মধ্যে একজন উপস্থিত থাকলে, এটি ডিফল্ট রেফারেন্স সমতা অপারেটরটি ব্যবহার করবে, সমস্ত বস্তুর জন্য এটির জন্য কোনও ওভারলোড নেই। 1

এই ঘটনাটি জেনেও আসল প্রশ্নটি হ'ল: কেন এটি এইভাবে ডিজাইন করা হয়েছিল এবং সংকলকটি কেন এটি নিজের মতো করে বের করে না? অনেক লোক বলছেন এটি কোনও ডিজাইনের সিদ্ধান্ত ছিল না, তবে আমি ভাবতে চাই যে এটি এইভাবে চিন্তা করা হয়েছিল, বিশেষত সমস্ত বস্তুর ডিফল্ট সমতা অপারেটর রয়েছে regarding

সুতরাং, সংকলক স্বয়ংক্রিয়ভাবে !=অপারেটরটি তৈরি করে না কেন ? মাইক্রোসফ্ট থেকে কেউ এটি নিশ্চিত না করা পর্যন্ত আমি নিশ্চিতভাবে জানতে পারি না, তবে আমি এই বিষয়গুলিতে যুক্তি থেকে নির্ধারণ করতে পারি।


অপ্রত্যাশিত আচরণ রোধ করার জন্য

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

এটি আপনাকে ওভারলোড করতে বাধ্য করার শর্তাবলী, ডিফল্ট আচরণে যাওয়ার পরিবর্তে, আমি কেবল দৃ firm়তার সাথে বলতে পারি যে এটি স্ট্যান্ডার্ড (EMCA-334 17.9.2) 2 এ রয়েছে । মানটি কেন তা নির্দিষ্ট করে না। আমি বিশ্বাস করি যে এটি সি #+ এর কাছ থেকে অনেক আচরণ orrowণ নিয়েছে তার কারণেই। এটি সম্পর্কে আরও নীচে দেখুন।


আপনি যখন ওভাররাইড করবেন !=এবং ==, আপনাকে বুলে ফিরতে হবে না।

এটি সম্ভবত অন্য কারণ reason সি # তে, এই ফাংশন:

public static int operator ==(MyClass a, MyClass b) { return 0; }

এটির মতো বৈধ:

public static bool operator ==(MyClass a, MyClass b) { return true; }

আপনি যদি বুল ব্যতীত অন্য কোনও কিছু ফিরিয়ে দিচ্ছেন, সংকলক স্বয়ংক্রিয়ভাবে কোনও বিপরীত প্রকারটি নির্ধারণ করতে পারে না । তদ্ব্যতীত, আপনার অপারেটর যে ক্ষেত্রে ফিরে আসে তার ক্ষেত্রে , তাদের পক্ষে জেনারেট কোড তৈরি করার কোনও অর্থ হয় না যা কেবলমাত্র একটি নির্দিষ্ট ক্ষেত্রে উপস্থিত থাকে বা যেমন আমি উপরে বলেছি যে কোডটি সিএলআর এর ডিফল্ট আচরণকে আড়াল করে।


সি # সি ++ 3 থেকে অনেক ধার নেয়

সি # চালু হওয়ার সাথে সাথে এমএসডিএন ম্যাগাজিনে একটি নিবন্ধ ছিল যা সি # সম্পর্কে কথা বলেছিল:

অনেক বিকাশকারী আশা করেন যে ভিজুয়াল বেসিকের মতো লিখতে, পড়তে এবং বজায় রাখা সহজ ভাষা ছিল তবে এটি এখনও সি ++ এর শক্তি এবং নমনীয়তা সরবরাহ করে।

হ্যাঁ সি # এর জন্য ডিজাইনের লক্ষ্যটি ছিল সি -+ এর মতো প্রায় একই পরিমাণ শক্তি প্রদান, অনমনীয় প্রকারের সুরক্ষা এবং আবর্জনা-সংগ্রহের মতো সুবিধার জন্য কেবলমাত্র কিছুটা ত্যাগ sacrific সি #+ কে সি ++ এর পরে দৃ mode়ভাবে মডেল করা হয়েছিল।

আপনি জেনে অবাক হতে পারেন না যে সি ++ তে, সাম্যতা অপারেটরদের বুল ফিরিয়ে দিতে হবে না , যেমন এই উদাহরণ প্রোগ্রামে দেখানো হয়েছে

এখন, সি ++ সরাসরি না প্রয়োজন, পরিপূরক অপারেটর জমিদার আপনার। যদি আপনি উদাহরণ প্রোগ্রামে কোডটি সংকলিত করেন তবে আপনি দেখতে পাবেন এটি কোনও ত্রুটি ছাড়াই চলে। তবে, আপনি যদি লাইনটি যুক্ত করার চেষ্টা করেন:

cout << (a != b);

তুমি পাবে

সংকলক ত্রুটি C2678 (এমএসভিসি): বাইনারি '! =': কোনও অপারেটর পাওয়া যায় নি যা 'টেস্ট' টাইপের বাম-হাতের ক্রিয়াকলাপ গ্রহণ করে (বা কোনও গ্রহণযোগ্য রূপান্তর নেই) ``

সুতরাং, যদিও সি ++ নিজেই আপনাকে জোড়ায় অতিরিক্ত চাপের প্রয়োজন নেই, এটি আপনাকে কোনও সমতা অপারেটরটি ব্যবহার করতে দেয় না যা আপনি কাস্টম ক্লাসে ওভারলোড করেন নি। এটি নেট। এ নেট বৈধ, কারণ সমস্ত বস্তুর একটি ডিফল্ট থাকে; সি ++ দেয় না।


১. পার্শ্ব নোট হিসাবে, সি # স্ট্যান্ডার্ডের এখনও আপনার অপরেটরগুলির জুড়িটি ওভারলোড করা প্রয়োজন যদি আপনি কোনও একটির ওভারলোড করতে চান। এটি স্ট্যান্ডার্ডের একটি অংশ এবং কেবল সংকলক নয় । তবে, আপনি অন্য ভাষায় লিখিত। নেট লাইব্রেরিতে একই রকমের প্রয়োজনীয়তা নেই এমন সময়ে কোন অপারেটরকে কল করতে হবে তা নির্ধারণের বিষয়ে একই বিধিগুলি।

2. ইএমসিএ -৩৩৪ (পিডিএফ) ( http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf )

৩. এবং জাভা, কিন্তু এখানে আসলে এটি বিন্দু নয়


75
" আপনাকে বুলে ফিরতে হবে না " .. আমার মনে হয় এটি আমাদের উত্তর ঠিক আছে; সাবাশ. যদি! (O1 == o2) এমনকি ভাল-সংজ্ঞায়িত না হয়, তবে আপনি মানটি এটির উপর নির্ভর করতে পারবেন না।
ব্রায়ান গর্ডন

10
লজিক্যাল অপারেটর সম্পর্কিত বিষয়টিতে আপনি বাক্যে দ্বিগুণ-নেতিবাচক ব্যবহার করেছেন, "সি # আপনাকে দুটির মধ্যে একটিরও ওভাররাইড করতে দেয় না" যার আসল যুক্তিযুক্ত অর্থ "সি # আপনাকে দুটির মধ্যে একটিরও ওভাররাইড করতে দেয়"।
ড্যান ডিপ্লো

13
@ ড্যান ডিপ্লো, এটি ঠিক আছে, এটি করা বা না করা আমার পক্ষে নিষিদ্ধ নয় not
ক্রিস্টোফার কারেনস 3:51

6
যদি সত্য হয় তবে আমার সন্দেহ হয় # 2 সঠিক; তবে এখন প্রশ্ন উঠেছে, এ ছাড়া ==আর কিছু ফেরত দেওয়ার অনুমতি দেবেন কেন bool? আপনি যদি কোনও ফেরত দেন তবে আপনি intএটি আর শর্তসাপেক্ষ বিবৃতি হিসাবে ব্যবহার করতে পারবেন না। if(a == b)আর সংকলন করা হবে না। আলোচ্য বিষয়টি কি?
ব্লুরাজা - ড্যানি পিফ্লুঘিওফ্ট

2
আপনি যে কোনও বস্তুকে বুলের সাথে অন্তর্নিহিত রূপান্তর রয়েছে (অপারেটর ট্রু / ভুয়া) ফেরত দিতে পারেন তবে এটি কোথায় কার্যকর হবে তা দেখতে আমি ব্যর্থ।
স্টিফান ড্রাগেনভ

53

সম্ভবত যদি কারও জন্য ত্রি-মূল্যবান যুক্তি (যেমন null) প্রয়োগ করা প্রয়োজন । যেমন - এএনএসআই স্ট্যান্ডার্ড এসকিউএল, উদাহরণস্বরূপ - ইনপুটগুলির উপর নির্ভর করে অপারেটরদের কেবল উপেক্ষিত করা যায় না।

আপনার কেস থাকতে পারে যেখানে:

var a = SomeObject();

এবং a == trueফিরে আসে falseএবং a == falseফিরে আসে false


1
আমি এই ক্ষেত্রে বলব, যেহেতু aকোনও বুলিয়ান নয় আপনার এটির সাথে তিন-রাষ্ট্রীয় এনামের সাথে তুলনা করা উচিত, বাস্তব trueবা নয় false
ব্রায়ান গর্ডন

18
যাইহোক, আমি বিশ্বাস করতে পারি না কেউই ফাইল নটফাউন্ড রসিকতার রেফারেন্স করেছে ..
ব্রায়ান গর্ডন

28
যদি a == trueহয় falseতাহলে আমি সবসময় আশা a != trueকরা trueথাকা সত্ত্বেও a == falseহচ্ছেfalse
Fede

20
@ ফেড মাথায় পেরেক মারলেন। এই প্রশ্নের সাথে আসলেই কিছু করার নেই - আপনি ব্যাখ্যা করছেন যে কেউ কেন ওভাররাইড করতে চায় ==, কেন তাদের উভয়কেই ওভাররাইড করতে বাধ্য করা উচিত নয়।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট 21

6
@ ইয়াক - হ্যাঁ, একটি ভাল পূর্বনির্ধারিত প্রয়োগ রয়েছে: এটি সাধারণ ঘটনা। এমনকি আপনার উদাহরণেও এর ডিফল্ট বাস্তবায়ন !=সঠিক হবে। ইন অত্যন্ত বিরল ক্ষেত্রে যেখানে আমরা চাই চাই x == yএবং x != yউভয়ই হতে মিথ্যাতে (আমি একটি একক উদাহরণ যে অর্থে তোলে মনে করা যাবে না) , তারা এখনও ডিফল্ট বাস্তবায়ন ওভাররাইড করতে ও তাদের নিজস্ব প্রদান করতে পারে। সর্বদা সাধারণ কেসটিকে ডিফল্ট করুন!
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

25

অনেক ক্ষেত্রে সি ++ এর চেয়ে সি-ডিফারেন্ড করা বাদে, আমি সবচেয়ে ভাল ব্যাখ্যাটি ভাবতে পারি যে কোনও কোনও ক্ষেত্রে আপনি "সাম্যতা" প্রমাণ করার চেয়ে "সাম্য নয়" প্রমাণ করার ক্ষেত্রে কিছুটা ভিন্ন পন্থা অবলম্বন করতে পারেন।

স্পষ্টতই স্ট্রিং তুলনার সাথে, উদাহরণস্বরূপ, আপনি returnযখন সামঞ্জস্যহীন অক্ষরগুলি দেখেন তখন সাম্যের জন্য এবং লুপের বাইরে পরীক্ষা করতে পারেন। তবে এটি আরও জটিল সমস্যার সাথে এতটা পরিষ্কার নাও হতে পারে। পুষ্প ফিল্টার মনে আসে; এটি খুব সহজ দ্রুত বলতে যদি উপাদান হয় না যদি উপাদান বলতে সেটে কিন্তু কঠিন হয় সেটে। একই returnকৌশলটি প্রয়োগ করতে পারে, কোডটি খুব সুন্দর নাও হতে পারে।


6
দুর্দান্ত উদাহরণ; আমি মনে করি আপনি এর কারণেই রয়েছেন। একটি সাধারণ !আপনাকে সাম্যতার জন্য একটি একক সংজ্ঞায় লক করে, যেখানে একটি অবহিত কোডার এবং উভয়ই অনুকূল করতে পারে । ==!=
ইয়াক

13
সুতরাং এটি ব্যাখ্যা করে যে কেন তাদের বাধ্য করা উচিত নয়, কেন তাদের উভয়কেই ওভাররাইড করার বিকল্প দেওয়া উচিত ।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

1
সেই শিরাতে তাদের উভয়কেই অনুকূল করতে হবে না , তাদের উভয়ের একটি পরিষ্কার সংজ্ঞা দিতে হবে
জেসপার

22

আপনি যদি নেট উত্সে == এবং! = এর ওভারলোডগুলির বাস্তবায়নগুলি দেখেন তবে তারা প্রায়শই প্রয়োগ করেন না! = হিসাবে! (বাম == ডান)। তারা এটিকে সম্পূর্ণরূপে প্রয়োগ করে (যেমন ==) অবহেলিত যুক্তি দিয়ে। উদাহরণস্বরূপ, ডেটটাইম প্রয়োগগুলি == হিসাবে

return d1.InternalTicks == d2.InternalTicks;

এবং! = হিসাবে

return d1.InternalTicks != d2.InternalTicks;

আপনি যদি (বা সংকলক এটি স্পষ্টভাবে এটি করে থাকে) বাস্তবায়ন করতে হয়! = হিসাবে

return !(d1==d2);

তারপরে আপনি আপনার ক্লাসটি যে বিষয়গুলি উল্লেখ করছেন তার মধ্যে == এবং! = এর অভ্যন্তরীণ বাস্তবায়ন সম্পর্কে একটি ধারণা তৈরি করছেন। এই ধারনা এড়ানো তাদের সিদ্ধান্তের পিছনে দর্শন হতে পারে।


17

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

যদি আপনি == ওভাররাইড করেন তবে বেশিরভাগ ধরণের শব্দার্থক বা কাঠামোগত সাম্য সরবরাহ করার সম্ভাবনা রয়েছে (উদাহরণস্বরূপ, ডেটটাইমস সমান যদি তাদের ইন্টারনালটিক্সের বৈশিষ্ট্যগুলি সমান হয় তবে তারা বিভিন্ন উদাহরণ হতে পারে), তবে আপনি অপারেটরের ডিফল্ট আচরণ পরিবর্তন করছেন অবজেক্ট, যা সমস্ত .NET অবজেক্টের পিতামাতা। == অপারেটর, সি # তে একটি পদ্ধতি, যার ভিত্তি বাস্তবায়ন অবজেক্ট.অপারেটর (==) একটি রেফারেন্সিয়াল তুলনা করে। অবজেক্ট.ওপ্রেটর (! =) হ'ল আরেকটি ভিন্ন পদ্ধতি, যা একটি রেফারেনশিয়াল তুলনাও করে।

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

যাইহোক, অপারেটরগুলি, পদ্ধতিগুলির সাথে খুব একইভাবে প্রয়োগ করা হলেও, ধারণামূলকভাবে জোড়ায় কাজ করে; == এবং! =, <এবং>, এবং <= এবং> =। এক্ষেত্রে কোনও ভোক্তার দৃষ্টিকোণ থেকে এটি বিবেচনা করা অযৌক্তিক হবে! = == এর চেয়ে আলাদাভাবে কোনও কাজ করেছে। সুতরাং, সংকলকটি ধরেই নেওয়া যায় না যে সব ক্ষেত্রে a! = B ==! (A == b), তবে এটি সাধারণত প্রত্যাশিত যে == এবং! = একই ধরণের কাজ করা উচিত, তাই সংকলকটি বাহিনী আপনি জোড়ায় প্রয়োগ করতে হবে, তবে আপনি আসলে এটি শেষ করছেন। যদি, আপনার শ্রেণীর জন্য, a! = B ==! (A == খ), তবে কেবল! = অপারেটরটি ব্যবহার করে কার্যকর করুন! (==), তবে যদি সেই নিয়ম আপনার অবজেক্টের জন্য সমস্ত ক্ষেত্রে ধরে না রাখে (উদাহরণস্বরূপ, , যদি কোনও নির্দিষ্ট মানের সাথে সমান বা অসম বৈধ নয়) তবে আপনাকে আইডিইর চেয়ে স্মার্ট হতে হবে।

সত্যিকারের প্রশ্নটি জিজ্ঞাসা করা উচিত কেন <এবং> এবং <= এবং> = তুলনামূলক অপারেটরগুলির জন্য যুগল যা সংখ্যায় প্রয়োগ করা উচিত, যখন সংখ্যাসূচক ক্ষেত্রে! (A <b) == a> = b এবং! (A> খ) == ক <= বি। আপনি যদি একটিকে ওভাররাইড করে থাকেন তবে আপনাকে চারটি বাস্তবায়ন করা উচিত এবং আপনার সম্ভবত == ((এবং! =) ওভাররাইড করা প্রয়োজন, কারণ (a <= b) == (a == b) যদি শব্দার্থগত হয় তবে সমান খ।


14

যদি আপনি নিজের কাস্টম টাইপের জন্য ওভারলোড == করেন না, এবং না! = তবে এটি হ'ল! = অবজেক্টের জন্য অপারেটর! = অবজেক্ট যেহেতু সবকিছুই বস্তু থেকে উদ্ভূত, এবং এটি কাস্টমটাইপ! = কাস্টম টাইপের চেয়ে অনেক আলাদা হবে।

এছাড়াও ভাষা নির্মাতারা সম্ভবত কোডারদের পক্ষে সর্বাধিক নমনীয়তাটি মঞ্জুর করার জন্য এটি চেয়েছিলেন এবং যাতে আপনি কী করতে চান তা অনুধাবন করে না।


আপনি এই প্রশ্নটি অনুপ্রাণিত করেছেন: স্ট্যাকওভারফ্লো.com
ব্রায়ান গর্ডন

2
নমনীয়তার কারণগুলি এমন অনেকগুলি বৈশিষ্ট্যগুলিতে প্রয়োগ করা যেতে পারে যা তারা ছেড়ে দেওয়ার সিদ্ধান্ত নিয়েছে, উদাহরণস্বরূপ ব্লগস.এমএসএন / বি / এরিক্লিপার্ট / অর্চিভ / ২০১৮ / ০/0 / ২৩ / ২।। সুতরাং এটি তাদের পছন্দটি ব্যাখ্যা করে না সমতা অপারেটরগুলির বাস্তবায়ন।
স্টিফান ড্রাগেনভ

এটি একটি খুব আকর্ষণীয়। দেখে মনে হচ্ছে এটি একটি দরকারী বৈশিষ্ট্য হবে। কেন তারা এটিকে ফেলে রেখেছিল তা আমার ধারণা নেই।
ক্রিস মুলিনস

11

এটিই আমার মনে প্রথমে আসে:

  • সাম্য পরীক্ষার তুলনায় অসমতার পরীক্ষা যদি খুব দ্রুত হয় তবে কী হবে ?
  • কিছু ক্ষেত্রে যদি আপনি উভয়ই ফিরিয়ে দিতে চান এবংfalse==!= (যেমন যদি কোনও কারণে তাদের তুলনা করা যায় না)

5
প্রথম ক্ষেত্রে আপনি তখন বৈষম্য পরীক্ষার ক্ষেত্রে সাম্যতা পরীক্ষার প্রয়োগ করতে পারেন।
স্টেফান ড্রাগেনভ

দ্বিতীয় ক্ষেত্রে যেমন কাঠামোগত ভেঙে যায় Dictionaryএবং Listযদি আপনি তাদের সাথে আপনার কাস্টম প্রকারটি ব্যবহার করেন।
স্টিফান ড্রাগেনভ

2
@Stefan: Dictionaryব্যবহারসমূহ GetHashCodeএবং Equalsনা অপারেটর। Listব্যবহার Equals
ড্যান আব্রামভ

6

ঠিক আছে, এটি সম্ভবত একটি নকশা পছন্দ, তবে আপনি যেমন বলেছিলেন, x!= yতেমনটি হবে না !(x == y)। একটি ডিফল্ট বাস্তবায়ন যোগ না করে, আপনি নিশ্চিত যে আপনি একটি নির্দিষ্ট বাস্তবায়ন বাস্তবায়ন করতে ভুলবেন না। এবং এটি যদি সত্যিই তুচ্ছ হিসাবে আপনি বলেন, আপনি কেবল অন্য ব্যবহার করে একটি বাস্তবায়ন করতে পারেন। আমি দেখতে পাচ্ছি না এটি কীভাবে 'খারাপ অনুশীলন'।

সি # এবং লুয়ার মধ্যেও কিছু অন্যান্য পার্থক্য থাকতে পারে ...


1
একে অপরের শর্তে কার্যকর করার অনুশীলন। আমি এটি অন্যথায় সম্পন্ন করে দেখেছি - যা ত্রুটিযুক্ত।
স্টিফান ড্রাগেনভ

3
এটি প্রোগ্রামার সমস্যা, সি # এর সমস্যা নয়। প্রোগ্রামাররা এই অধিকারটি প্রয়োগ করতে ব্যর্থ হয়, অন্য ক্ষেত্রেও ব্যর্থ হবে।
গোলেজট্রোল

@ গোলেজট্রোল: আপনি কি লুয়া রেফারেন্সটি ব্যাখ্যা করতে পারবেন? আমি লুয়ার সাথে মোটেও পরিচিত নই, তবে আপনি উল্লেখ করেছেন বলে মনে হচ্ছে কিছু।
zw324

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

6

আপনার প্রশ্নের মূল শব্দগুলি হ'ল " কেন " এবং " আবশ্যক "।

ফলস্বরূপ:

এটি এইভাবে উত্তর দেওয়ার কারণ তারা এটি এটির জন্য ডিজাইন করেছিল, সত্য ... তবে আপনার প্রশ্নের "কেন" অংশের উত্তর দিচ্ছেন না।

এগুলি উভয়কে স্বতন্ত্রভাবে ওভাররাইড করতে সহায়ক হতে পারে এমন উত্তর দেওয়া সত্য ... তবে আপনার প্রশ্নের "অবশ্যই" অংশটির উত্তর না দেওয়া।

আমি মনে করি সহজ উত্তর আছে যে নয় কোনো বিশ্বাসযোগ্য কারণ C # এর প্রয়োজন উভয় ওভাররাইড করতে আপনি।

আপনি যে ভাষায় শুধুমাত্র ওভাররাইড অনুমতি থাকবে ==, এবং আপনি একটি ডিফল্ট বাস্তবায়ন প্রদান !=করে !যে। আপনি যদি ওভাররাইড করতে চান !=তবে এটিও করুন।

এটি একটি ভাল সিদ্ধান্ত ছিল না। মানুষের ডিজাইন ভাষা, মানুষ নিখুঁত নয়, সি # নিখুঁত নয়। শ্রাগ এবং কিউইডি


5

এখানে দুর্দান্ত উত্তর যুক্ত করতে:

আপনি যখন কোনও অপারেটরে প্রবেশ করার চেষ্টা করবেন এবং পরিবর্তে কোনও অপারেটরে গিয়ে শেষ করবেন , তখন ডিবাগারে কী ঘটবে তা বিবেচনা করুন ! বিভ্রান্তির বিষয়ে কথা বলুন!!===

এটি উপলব্ধি করে যে সিএলআর আপনাকে অপারেটরগুলির মধ্যে একটি বা অন্যটি ছাড়ার স্বাধীনতা দেয় - কারণ এটি অবশ্যই অনেকগুলি ভাষা নিয়ে কাজ করে। কিন্তু সি # CLR বৈশিষ্ট্য প্রকাশক নেই (উদাহরণ প্রচুর আছে ref(: যেমন আয় এবং স্থানীয়দের, উদাহরণস্বরূপ), এবং বৈশিষ্ট্য CLR নিজেই না বাস্তবায়নের উদাহরণ প্রচুর using, lock, foreach, ইত্যাদি)।


3

প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি ব্যতিক্রমী জটিল লজিক্যাল স্টেটমেন্টের সিনট্যাক্টিকাল রিআরঞ্জমেন্টস। এই বিষয়টি মাথায় রেখে, আপনি কি অসমতার ক্ষেত্রে কোনও সংজ্ঞা না দিয়েই সাম্যের ক্ষেত্রে সংজ্ঞা দিতে পারেন? উত্তর না হয়। কোন অবজেক্টের জন্য a অবজেক্ট বি এর সমান হতে হবে, তারপরে অবজেক্ট a এর সমান বি এর বিপরীতটিও সত্য হতে হবে। এটি দেখানোর আর একটি উপায়

if a == b then !(a != b)

এটি ভাষার পক্ষে বস্তুর সাম্য নির্ধারণের সুনির্দিষ্ট ক্ষমতা প্রদান করে। উদাহরণস্বরূপ, তুলনা NULL! = NULL একটি সাম্যতা সিস্টেমের সংজ্ঞাতে একটি রেঞ্চ ফেলে দিতে পারে যা একটি অসমতার বিবৃতি কার্যকর করে না।

এখন, ধারণাটির ক্ষেত্রে! = কেবল হিসাবে প্রতিস্থাপনযোগ্য সংজ্ঞা হচ্ছে

if !(a==b) then a!=b

আমি এই নিয়ে তর্ক করতে পারি না। তবে, সম্ভবত এটি সি # ভাষার স্পেসিফিকেশন গোষ্ঠীর সিদ্ধান্ত ছিল যে প্রোগ্রামার স্পষ্টভাবে কোনও বস্তুর সাম্যতা এবং অসমতার সংজ্ঞা দিতে বাধ্য হয়


Nullকেবল একটি সমস্যা হবে কারণ এটির nullজন্য একটি বৈধ ইনপুট ==, যা এটি হওয়া উচিত নয়, যদিও স্পষ্টতই, এটি ব্যাপকভাবে সুবিধাজনক। ব্যক্তিগতভাবে, আমি কেবলমাত্র এটি মনে করি এটি বিপুল পরিমাণে অস্পষ্ট, opালু প্রোগ্রামিংয়ের অনুমতি দেয়।
নিকোডেমাস 13

2

সংক্ষেপে, বাধ্যতামূলক ধারাবাহিকতা।

'==' এবং '! =' হ'ল সর্বদা সত্য বিপরীত, আপনি তাদেরকে কীভাবে সংজ্ঞায়িত করেন, "সমান" এবং "সমান নয়" এর মৌখিক সংজ্ঞা দ্বারা যেমন সংজ্ঞায়িত করা হয়। কেবলমাত্র তাদের মধ্যে একটির সংজ্ঞা দিয়ে আপনি নিজেকে একটি সমতা অপারেটরের অসঙ্গতিতে উন্মুক্ত করেন যেখানে '==' এবং '! =' উভয়ই দুটি প্রদত্ত মানের জন্য সত্য বা উভয়ই মিথ্যা হতে পারে। আপনি উভয়কেই সংজ্ঞায়িত করতে হবে যেহেতু আপনি যখন কোনওটির সংজ্ঞা দেওয়ার জন্য নির্বাচন করেন তখন আপনার অবশ্যই অন্যটিকে যথাযথভাবে সংজ্ঞা দিতে হবে যাতে এটি "সমতা" সম্পর্কে আপনার সংজ্ঞা কী তা স্পষ্টভাবে স্পষ্ট হয়। সংকলকটির অন্যান্য সমাধানটি কেবল আপনাকে '==' ও '! =' ওভাররাইড করার অনুমতি দেয় এবং অন্যটিকে সহজাতভাবে অবহেলিত হিসাবে ছেড়ে যায় as স্পষ্টতই, এটি সি # সংকলকের ক্ষেত্রে হয়নি এবং আমি নিশ্চিত সেখানে '

আপনার যে প্রশ্নটি করা উচিত তা হ'ল "আমাকে অপারেটরদের ওভাররাইড করার দরকার কেন?" এটি একটি দৃ a় সিদ্ধান্ত যা দৃ which় যুক্তির প্রয়োজন requires অবজেক্টের জন্য, '==' এবং '! =' রেফারেন্সের সাথে তুলনা করুন। আপনি যদি তাদেরকে রেফারেন্সের সাথে তুলনা না করার জন্য ওভাররাইড করতে চান তবে আপনি একটি সাধারণ অপারেটরের অসঙ্গতি তৈরি করছেন যা অন্য কোনও বিকাশকারীদের পক্ষে স্পষ্ট নয় যারা এই কোডটি ব্যবহার করেছিলেন। আপনি যদি এই প্রশ্নটির "এই দুটি উদাহরণের সমতুল্য ?," জিজ্ঞাসা করার চেষ্টা করছেন, তবে আপনার অবশ্যই আইক্যুয়েলিটি বাস্তবায়ন করা উচিত, সমান সংজ্ঞা () সংজ্ঞায়িত করতে হবে এবং সেই পদ্ধতি কলটি ব্যবহার করা উচিত।

শেষ অবধি, আইকুয়েটেবল () একই যুক্তির জন্য নোটইক্যুলস () সংজ্ঞায়িত করে না: সমতা অপারেটরের অসঙ্গতিগুলি খোলার সম্ভাবনা। নোটএকএল () এর সর্বদা ফিরে আসা উচিত! সমান ()। সমাপ্তি () সমীকরণ () প্রয়োগকারী শ্রেণীর কাছে নোটইক্যালস () এর সংজ্ঞাটি খোলার মাধ্যমে আপনি আবারও সাম্যতা নির্ধারণে ধারাবাহিকতার বিষয়টি জোর করছেন।

সম্পাদনা: এটি কেবল আমার যুক্তি।


এটি অযৌক্তিক। কারণ যদি ধারাবাহিকতা থাকে তবে বিপরীতটি প্রযোজ্য: আপনি কেবলমাত্র প্রয়োগ করতে সক্ষম হবেন operator ==এবং সংকলকটি অনুমান করবে operator !=। সব পরে, এই কি তার জন্য নেই operator +এবং operator +=
কনরাড রুডল্ফ

1
foo + = বার; foo = foo + বার; এটি কোনও অপারেটর নয়।
blenderfreaky

তারা যদি প্রকৃতপক্ষে হয় 'সবসময় সত্য বিপরীতের', তারপর যে একটি কারণ হতে পারে জন্য স্বয়ংক্রিয়ভাবে সংজ্ঞায়িত a != bহিসাবে !(a == b)(যা কি না C # এর নেই) ...।
অ্যান্ড্রুফ

-3

সম্ভবত কেবল এমন কিছু যা তারা ভাবেনি তার করার সময় নেই।

আমি যখন ওভারলোড == করি তখন আমি সর্বদা আপনার পদ্ধতিটি ব্যবহার করি। তারপরে আমি এটি অন্যটিতে ব্যবহার করব।

আপনি ঠিক বলেছেন, অল্প পরিমাণ কাজের সাথে সংকলকটি এটি আমাদের বিনামূল্যে দিতে পারত।

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