সি # পার্থক্য == এবং সমান () এর মধ্যে


548

আমার একটি সিলভারলাইট অ্যাপ্লিকেশনটিতে একটি শর্ত রয়েছে যা 2 টি স্ট্রিংয়ের সাথে তুলনা করে, কোনও কারণে যখন আমি ==এটি ব্যবহার করি তখন সত্য প্রত্যাবর্তনের সময় এটি মিথ্যা.Equals() প্রত্যাবর্তন করে ।

কোডটি এখানে:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

কেন এমন ঘটনা ঘটছে?



8
স্ট্রিং ওভাররাইড ==, তবে অপারেটরগুলি বহুকোষী নয়। এই কোডে ==অপারেটরটি টাইপ করা হয় object, যা একটি মানের পরিবর্তে একটি পরিচয় তুলনা করে।
ড্রয় নোকস

12
@ ড্রউনোকেসের মন্তব্যে প্রসারিত করার জন্য: সংকলক অপারেশনগুলির ==সংকলন-সময়ের ধরণের ভিত্তিতে একটি ওভারলোড চয়ন করে। Contentসম্পত্তি object। অপারেটরগুলি ভার্চুয়াল নয়, সুতরাং এর একটি ডিফল্ট বাস্তবায়ন ==বলা হয়, একটি রেফারেন্স সমতার তুলনা করে। সমান সাথে, কলটি ভার্চুয়াল পদ্ধতিতে যায় object.Equals(object); stringএই পদ্ধতিটিকে ওভাররাইড করে এবং স্ট্রিং সামগ্রীতে একটি সাধারণ তুলনা সম্পাদন করে। এমএসডিএন.মাইক্রোসফট . /en-us/library/fkfd9eh8(v=vs.110).aspx এবং রেফারেন্সসোর্স.মাইক্রোসফট /#mscorlib/system/string.cs,507 দেখুন ।
ফুগ

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

1
সংকলক সতর্কতা পড়ার পরামর্শের জন্য @ জেপ্পস্টিগনিয়েলসন +1 আরও ভাল: প্রত্যেককে তাদের দিকে মনোযোগ দিতে বাধ্য করার জন্য সতর্কতা-হিসাবে-ত্রুটিযুক্ত বিকল্পটি চালু করুন।
ফুগ

উত্তর:


429

যখন ==টাইপের একটি অভিব্যক্তিতে ব্যবহৃত হয় object, তখন এটি সমাধান হবে System.Object.ReferenceEquals

Equalsএটি কেবল একটি virtualপদ্ধতি এবং এর মতো আচরণ করে, সুতরাং ওভাররাইড করা সংস্করণটি ব্যবহার করা হবে (যা stringধরণের বিষয়বস্তুগুলির সাথে তুলনা করে)।


56
অপারেটরটি ক্লাসে সুনির্দিষ্টভাবে প্রয়োগ না করা হলে
ডমিনিক ক্রোনিন

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

4
@ ডোমিনিক ক্রোনিন আমি বিশ্বাস করি যে আপনার প্রথম বিবৃতিটি ঠিক == এ আপত্তি করার সমাধান করবে তবে আপনার দ্বিতীয় বিবৃতি যা অপারেটর ওভারলোডগুলি একইভাবে সমাধান করে তা নয়। এগুলি একেবারেই পৃথক, এজন্যই। সমাপ্তি স্ট্রিংয়ের সাথে সমাধান করবে যখন == আপত্তিটির সমাধান করবে।
মাইককুলস

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

4
@ ডোমিনিক্রোনিন বিভ্রান্তিমূলক অংশটি হল যে virtualপদ্ধতিটি রেজোলিউশনটি উদাহরণের প্রকৃত রানটাইম ধরণের উপর নির্ভর করে, যেখানে অপারেটর ওভারলোড রেজোলিউশনে এটি সম্পূর্ণ উপেক্ষা করা হয় এবং এটি আমার উত্তরটির পুরো বিষয়টিই।
মেহরদাদ আফশারি

314

যখন স্ট্রিংয়ের সাথে কোনও অবজেক্ট রেফারেন্স তুলনা করা হয় (এমনকি যদি অবজেক্ট রেফারেন্সটি একটি স্ট্রিংকে বোঝায়) ==তখন স্ট্রিং শ্রেণীর জন্য নির্দিষ্ট অপারেটরের বিশেষ আচরণকে উপেক্ষা করা হয়।

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

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

আউটপুটটি হ'ল:

True True True
False True True
False False True

8
চিহ্নিত করা. '==' অপারেটর অবজেক্টের রেফারেন্সের (অগভীর তুলনা) তুলনা করে Eকুয়ালগুলি () বস্তুর সামগ্রীর (গভীর তুলনা) তুলনা করে। যেমনটি @ মেহর্দাদ বলেছিলেন, গভীরতর সামগ্রীর তুলনা সরবরাহের জন্য কোয়ালিটি () ওভাররাইড করা হয়।
অ্যান্ড্রু

1
কারণ আমি মনে করি এটা জোর কি মূল্যবান আমি এখানে পোস্ট ছাড়বে না যেহেতু আপনি গভীর মনোযোগ পরিশোধ করা এটা বুঝতে হবে ঘটছে। (এবং আমি কোডটি খুব সঠিক এবং ভুল সমঝোতা উপযুক্ত হয় প্রকট মনে।) আমি আশা করি রেটিং নিচে 0. যেতে হবে না
BlueMonkMN

5
নিশ্চয় স্ট্রিং একটি কাস্টম == অপারেটর প্রয়োগ করে। যদি এটি তখন না হয় তবে == ব্যবহারটি সামগ্রীটির তুলনা করবে না। স্ট্রিং এখানে ব্যবহারের জন্য একটি খারাপ উদাহরণ, কারণ এটি আমাদের সাধারণ ক্ষেত্রে বুঝতে সাহায্য করে না যেখানে কোনও কাস্টম অপারেটর সংজ্ঞায়িত করা হয়নি।
ডোমিনিক ক্রোনিন

6
মহাকাব্য কোড উদাহরণের জন্য +1, যা আমাকে এটি উপলব্ধি করে। স্ট্যাটিক টাইপের (বাম হাতের সাইড টাইপ) অবজেক্ট হওয়ার সাধারণ অবস্থা এবং স্ট্যাটিক টাইপের (/ আরএইচএস টাইপ) স্ট্রিংয়ের নির্দিষ্ট কেস দেখায়। এবং স্ট্রিং ইন্টার্নিং উপর ভাল ছোঁয়া।
বারলপ

2
স্ট্রিং ইন্টার্নিংয়ের কারণে @ আবদসামরিতান
আলেকজান্ডার ডার্ক

46

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

যখন আমি কোনও নতুন ধরণের সাথে কাজ করছি যার সংজ্ঞাটি প্রবাহে বা জেনেরিক অ্যালগরিদম লেখার ক্ষেত্রে রয়েছে, তখন আমি সেরা অনুশীলনটি নিম্নলিখিতটি দেখতে পাই

  • যদি আমি সি # তে রেফারেন্সগুলি তুলনা করতে চাই তবে আমি Object.ReferenceEqualsসরাসরি ব্যবহার করি (জেনেরিক ক্ষেত্রে প্রয়োজন হয় না)
  • আমি যদি ব্যবহার করা মানগুলির তুলনা করতে চাই EqualityComparer<T>.Default

কিছু ক্ষেত্রে যখন আমি মনে করি যে এর ব্যবহার ==অস্পষ্ট হয় তখন আমি স্পষ্টতই Object.Referenceঅস্পষ্টতা অপসারণ করতে কোডের সমান ব্যবহার করব ।

এরিক লিপার্ট সম্প্রতি সিএলআর-তে সাম্যতার 2 টি পদ্ধতি কেন তা নিয়ে একটি ব্লগ পোস্ট করেছিলেন। এটি পড়া মূল্য


ভাল জ্যারেড, আপনি সরাসরি জেফের বিখ্যাত লঙ্ঘন করেছেন "এখানে সেরা কোড কোনও কোড নয়” " এটি কি ন্যায়সঙ্গত? অন্যদিকে, আমি দেখতে পাচ্ছি যে এটি কোথা থেকে এসেছে এবং কেন শব্দার্থকে সুস্পষ্ট করা বাঞ্ছনীয় হতে পারে। এই ক্ষেত্রে, আমি বস্তুর সমতা নিয়ে কাজ করার পদ্ধতিটি খুব পছন্দ করি। এটি সংক্ষিপ্ত এবং দ্ব্যর্থহীন।
কনরাড রুডল্ফ

@ কনরাড, আমার সত্যিই বলা উচিত ছিল "যখন আমি কোনও প্রকারের সাথে অপরিচিত তখন আমি অনুধাবন করি যে সর্বোত্তম অনুশীলনটি নিম্নলিখিতটি"। হ্যাঁ ভিবিতে এখানে আরও ভাল শব্দার্থবিজ্ঞান রয়েছে কারণ এটি সত্যই মূল্য এবং রেফারেন্সের সাম্যকে আলাদা করে। সি # দুটোকে একসাথে মিশিয়ে তোলে এবং এটি মাঝে মধ্যে দ্বিধাদ্বন্দ্বের ত্রুটি ঘটায়।
জারেডপাড়

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

20

== অপারেটর

  1. যদি অপারেন্ডগুলি মান প্রকার হয় এবং তাদের মানগুলি সমান হয়, তবে এটি সত্য অন্যথায় মিথ্যা দেয়।
  2. অপারেন্ডগুলি যদি স্ট্রিং ব্যতীত রেফারেন্স টাইপ হয় এবং উভয়ই একই উদাহরণ (একই জিনিস) উল্লেখ করে তবে এটি সত্য অন্যথায় মিথ্যা দেয়।
  3. যদি অপারেন্ডগুলি স্ট্রিং টাইপ হয় এবং মানগুলি সমান হয়, তবে এটি সত্য অন্যথায় মিথ্যা দেয়।

.Equals

  1. অপারেশনগুলি যদি রেফারেন্স টাইপ হয় তবে এটি রেফারেন্স ইক্যুয়ালিটি সম্পাদন করে যা উভয়ই একই উদাহরণ (একই বস্তু) কে বোঝায় , এটি সত্য অন্যথায় মিথ্যা দেয়।
  2. অপারেন্ডস যদি মান প্রকার হয় তবে == অপারেটরের বিপরীতে এটি প্রথমে তাদের প্রকারের জন্য পরীক্ষা করে এবং যদি তাদের প্রকারগুলি একই হয় তবে এটি == অপারেটর সম্পাদন করে অন্যথায় এটি মিথ্যা প্রত্যাবর্তন করে।

2
এটি সঠিক নয়। ==অপারেটর কোন প্রকার, শুধু স্ট্রিং এর জন্য ওভারলোড করা যেতে পারে। কেবল স্ট্রিংয়ের জন্য একটি বিশেষ-কেস ব্যতিক্রম বর্ণনা করা অপারেটরের শব্দার্থতাকে ভুল উপস্থাপন করে। এটি আরও সঠিক হবে, যদিও এটি সম্ভবত ভয়াবহভাবে কার্যকর নয়, এটি বলার অপেক্ষা রাখে না "অপারেশনগুলি যদি রেফারেন্স টাইপ হয় তবে অপারেশনগুলি একই বস্তুকে উল্লেখ করে যদি এটি কার্যকর হয়, যদি না কোনও প্রযোজ্য ওভারলোড থাকে, তবে সেই ক্ষেত্রে সেই ওভারলোডের প্রয়োগ ফলাফল নির্ধারণ করে "। Equalsযুক্ত জটিলতার সাথে একই কথা সত্য যে এটি ভার্চুয়াল পদ্ধতি, সুতরাং এর আচরণ ওভাররাইডের পাশাপাশি ওভারলোড হওয়াও যায়।
ফোগ

19

প্রথমত, সেখানে হয় একটি পার্থক্য। সংখ্যার জন্য

> 2 == 2.0
True

> 2.Equals(2.0)
False

এবং স্ট্রিং জন্য

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

উভয় ক্ষেত্রেই ==তার চেয়ে বেশি কার্যকর আচরণ করে.Equals


2
আমি নিশ্চিত নই যে ==অপারেটরের সাথে ভাল জিনিস হওয়ার জন্য আমি অবিচ্ছেদ্য ধরণের জোরকে ভাসমান-বিন্দু প্রকারকে বিবেচনা করব । উদাহরণস্বরূপ, 16777216.0f সমান (int) 16777217, (ডাবল) 16777217.0, উভয়ই না উভয়ই উচিত? অবিচ্ছেদ্য ধরণের মধ্যে তুলনাগুলি ভাল, তবে ভাসমান-পয়েন্ট তুলনাগুলি কেবলমাত্র মানগুলির সাথে আইএমএইচও করা উচিত যা স্পষ্টভাবে মেলানো প্রকারগুলিতে কাস্ট করা হয়। একটি তুলনা floatএকটি ব্যতীত অন্য কিছু float, অথবা একটি doubleএকটি ব্যতীত অন্য কিছু double, আমাকে একটি প্রধান কোড গন্ধ যে ডায়গনিস্টিক ছাড়া কম্পাইল করা উচিত নয় যেমন হানা।
ক্যাট

1
@ সুপের্যাট আমি সম্মতি জানাই distress এটি এমন কষ্টকর যা x == yবোঝায় না x/3 == y/3(চেষ্টা করুন x = 5এবং y = 5.0)।
কর্নেল আতঙ্ক

আমি /পূর্ণসংখ্যা বিভাগের জন্য সি # এবং জাভা ডিজাইনের একটি ত্রুটি হিসাবে বিবেচনা করছি । প্যাসকেলেরdiv এবং এমনকি ভিবি.এনইটি'র ` are much better. The problems with == `আরও খারাপ, যদিও: x==yএবং y==zএটি বোঝায় না x==z(আমার আগের মন্তব্যে তিনটি সংখ্যা বিবেচনা করুন)। সম্পর্ক আপনার প্রস্তাবিত, এমনকি যদি হিসাবে xএবং yউভয় floatঅথবা উভয় double, x.equals((Object)y)পরোক্ষভাবে না যে 1.0f/x == 1.0f / y` (যদি আমি আমার druthers থাকত, তাহলে গ্যারান্টি হবে; এমনকি যদি ==ইতিবাচক পার্থক্য করে না এবং শূন্য, Equalsউচিত)।
সুপারক্যাট

এটি সাধারণ, কারণ সমান () এর প্রথম প্যারামিটারটি একটি স্ট্রিং!
হুইপল্যাশ

17

আমি যতদূর বুঝতে পারি উত্তরটি সহজ:

  1. == অবজেক্টের রেফারেন্সের তুলনা করে।
  2. .Equals বস্তুর সামগ্রীর তুলনা করে।
  3. String ডেটাটাইপগুলি সর্বদা সামগ্রীর তুলনার মতো কাজ করে।

আমি আশা করি আমি সঠিক এবং এটি আপনার প্রশ্নের উত্তর দিয়েছে।


15

আমি যুক্ত করব যে আপনি যদি নিজের বস্তুকে স্ট্রিংয়ে ফেলে দেন তবে এটি সঠিকভাবে কাজ করবে। এই কারণেই সংকলক আপনাকে একটি সতর্কবার্তা বলবে:

সম্ভাব্য অনিচ্ছাকৃত রেফারেন্স তুলনা; একটি মান তুলনা পেতে, 'স্ট্রিং' টাইপ করতে বাম দিকে কাস্ট করুন


1
যথাযথভাবে। @ ডোমিনিকক্রোনিন: সবসময় সংকলন-সময় সতর্কতাগুলি পর্যবেক্ষণ করুন। যদি আপনার কাছে থাকে object expr = XXX; if (expr == "Energy") { ... }, তবে যেহেতু বাম দিকের দিকটি সংকলন-টাইপ টাইপের object, তাই সংকলকটিকে ওভারলোডটি ব্যবহার করতে হবে operator ==(object, object)। এটি রেফারেন্স সমতার জন্য পরীক্ষা করে। যে দেব কিনা trueবা falseকারণ ভবিষ্যদ্বাণী করা কঠিন হতে পারে স্ট্রিং interning । আপনি যদি জানেন যে বাম-হাতটি হয় nullবা টাইপের stringহয় stringতবে ব্যবহারের আগে বাম-হাতটি cast ালুন ==
জেপ্পে স্টিগ নীলসন

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

5

যেহেতু .Equalএখনও পদ্ধতির স্থির সংস্করণটি উল্লেখ করা হয়নি, আমি সংক্ষিপ্ত বিবরণ এবং 3 টি বৈচিত্রের তুলনা করতে এখানে এটি যুক্ত করতে চাই।

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

যেখানে MyStringএকটি পরিবর্তনশীল যে কোড মধ্যে অন্য কোথাও থেকে আসে।

পটভূমি তথ্য এবং সংক্ষেপে:

জাভাতে ==স্ট্রিংগুলির তুলনা করতে ব্যবহার করা উচিত নয়। আপনার উভয় ভাষা ব্যবহার করতে হবে এবং এটি ব্যবহারের মাধ্যমে আপনাকে তা জানানোর ক্ষেত্রে আমি এটি উল্লেখ করছি== সি # তে আরও ভাল কিছু দিয়ে প্রতিস্থাপন যেতে ।

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

প্রস্তাবিত সমাধান:

কারণ জিনিসগুলির সাথে তুলনা ==করার .Equalsসময় ব্যবহার করা ঠিক একইরকম নয় , আপনি এর পরিবর্তে স্থির স্ট্রিং.একুয়ালস পদ্ধতি ব্যবহার করতে পারেন । এইভাবে, যদি উভয় পক্ষ একই ধরণের না হয় আপনি এখনও সামগ্রীর তুলনা করতে পারবেন এবং যদি কোনওটি শূন্য হয় তবে আপনি ব্যতিক্রম এড়াতে পারবেন।

   bool areEqual = String.Equals("Somestring", MyString);  

এটি লেখার জন্য আরও কিছুটা হলেও আমার মতে, এটি ব্যবহার করা আরও নিরাপদ।

মাইক্রোসফ্ট থেকে অনুলিপি করা কিছু তথ্য এখানে:

public static bool Equals (string a, string b);

পরামিতি

a দড়ি

প্রথম স্ট্রিং তুলনা করতে, বা null

b দড়ি

দ্বিতীয় স্ট্রিংটি তুলনা করতে, বা null

রিটার্নস Boolean

trueযদি মানটির মান aএকই হয় b; অন্যথায় false,। উভয় তাহলে aএবং bহয় null, পদ্ধতি আয় true


5

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

নিম্নলিখিত স্ক্রিনশটটি দুটি বস্তুর {int} - মানের তুলনা করার ফলাফলগুলি দেখায়

ভিএস ২০১7 থেকে উদাহরণ


2

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


2
আপনি এটি সামনে ফিরে আছে। শুরু করার জন্য সমান ("এনার্জি অ্যাটাক") ব্যর্থ হয় না, == হ'ল মিথ্যা ফেরত দেয়। == ব্যর্থ হয়েছে কারণ এটি স্ট্রিং নয়, বস্তু থেকে == ব্যবহার করছে।
মাইককুলস

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

2

@ ব্লুমোনকএমএন এর পূর্বের উত্তরের আরও একটি মাত্রা রয়েছে। অতিরিক্ত মাত্রাটি হ'ল @ দ্রাচিরের শিরোনাম প্রশ্নের উত্তর যেমনটি বলা হয়েছে তার উত্তরও নির্ভর করে যে আমরা কীভাবে মূল্যটিতে পৌঁছেছি string। বর্ণনা করা:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

আউটপুটটি হ'ল:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True

2

উত্তরে আরও একটি বিষয় যুক্ত করা হচ্ছে।

.EqualsTo() পদ্ধতি আপনাকে সংস্কৃতি এবং কেস সংবেদনশীলের সাথে তুলনা করার বিধান দেয়।


0

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

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

(*) প্রকারগুলি সাধারণত নিজেদের সাথে তুলনা করার জন্য কেবল ওভারলোড সাম্যতা বর্ধন করে তবে অন্যান্য বিশেষ ধরণের সাথে তুলনা করার জন্য সমতা অপারেটরটিকে ওভারলোড করা ধরণের পক্ষে কার্যকর হতে পারে; উদাহরণস্বরূপ, intথাকতে পারে (এবং আইএমএইচও করা উচিত ছিল কিন্তু না) তুলনা করার জন্য একটি সমতা অপারেটরগুলি সংজ্ঞায়িত করেfloat , যাতে 16777217 নিজেকে 16777216f এর সমান রিপোর্ট করে না। যেমন আছে, যেহেতু কোন অপারেটর সংজ্ঞায়িত করা হয়, সি # উন্নীত করা হবে intথেকে float, 16777216f তা rounding আগে সমতা-যাচাই অপারেটর পায়; অপারেটরটি তখন দুটি সমান ভাসমান-পয়েন্ট নম্বর দেখবে এবং তাদের সমান হিসাবে প্রতিবেদন করবে, যে গোল হয়েছে তা অজানা।


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

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

0

সত্যিই দুর্দান্ত উত্তর এবং উদাহরণ!

আমি কেবল দুজনের মধ্যে মৌলিক পার্থক্য যুক্ত করতে চাই,

অপারেটর যেমন ==পলিমারফিক হয় না, যখন Equalsহয়

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


-1

আমরা যখন কোনও বস্তু তৈরি করি তখন বস্তুর দুটি অংশ থাকে একটি হ'ল সামগ্রী এবং অন্যটি সেই বিষয়বস্তুর উল্লেখ to ==উভয় বিষয়বস্তু এবং রেফারেন্স তুলনা; equals()শুধুমাত্র বিষয়বস্তুর সাথে তুলনা করে

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq


1
এটি সত্য নয়। যদি aএবং bউভয় স্ট্রিং রেফারেন্স হয় তবে এর ফলাফলগুলি a == bএকই বস্তুর দিকে নির্দেশ করে কিনা তার উপর নির্ভর করে না।
ফোগ

-2

==

== অপারেটরটি যে কোনও ধরণের দুটি ভেরিয়েবলের সাথে তুলনা করতে ব্যবহার করা যেতে পারে এবং এটি কেবল বিটের সাথে তুলনা করে

int a = 3;
byte b = 3;
if (a == b) { // true }

দ্রষ্টব্য: ইন্টের বাম দিকে আরও শূন্য রয়েছে তবে আমরা এখানে সেটির যত্ন নিই না।

int a (00000011) == বাইট খ (00000011)

মনে রাখবেন == অপারেটর কেবল ভেরিয়েবলের বিটের প্যাটার্ন সম্পর্কে চিন্তা করে।

ব্যবহার == যদি দুটি রেফারেন্স (আদিম) হিপে একই বস্তুকে বোঝায়।

পরিবর্তনগুলি একটি রেফারেন্স বা আদিম কিনা নিয়মগুলি একই same

Foo a = new Foo();
Foo b = new Foo();
Foo c = a;

if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }

a == c সত্য a == খ মিথ্যা

বিট প্যাটার্নটি a এবং c এর জন্য সমান, তাই তারা == ব্যবহার করে সমান।

সমান():

সমান () পদ্ধতিটি দেখতে ব্যবহার করুন দুটি পৃথক বস্তু সমান কিনা

যেমন দুটি পৃথক স্ট্রিং অবজেক্ট যা উভয়ই "জেন" এর চরিত্রগুলিকে উপস্থাপন করে


2
এটি ভুল। নিম্নলিখিত বিবেচনা করুন: object a = 3; object b = 3; Console.WriteLine(a == b);। মানগুলির বিট নিদর্শনগুলি একই হলেও আউটপুটটি মিথ্যা। অপারেন্ডগুলির ধরণগুলিও গুরুত্বপূর্ণ। আপনার উদাহরণে আমরা জিরোর বিভিন্ন সংখ্যা সম্পর্কে "যত্ন না করি" এর কারণ হ'ল আমরা সমতুল্য অপারেটরকে কল করার সময় , অন্তর্নিহিত রূপান্তরের কারণে জিরোগুলির সংখ্যা আসলে একই
ফুগ

-2

সমান এবং == এর মধ্যে পার্থক্য কেবলমাত্র বস্তুর ধরণের তুলনা। অন্যান্য ক্ষেত্রে যেমন রেফারেন্সের ধরণ এবং মানের ধরণগুলি প্রায় একই রকম (উভয়ই বিট-বুদ্ধিমান সমতা হয় বা উভয়ই রেফারেন্স সমতা হয়)।

অবজেক্ট: সমান: বিট-বুদ্ধিমান সমতা ==: রেফারেন্স সমতা

স্ট্রিং: (স্ট্রিংয়ের জন্য সমান এবং == সমান, তবে স্ট্রিংগুলির মধ্যে একটিতে যদি বস্তুতে পরিবর্তিত হয়, তবে তুলনার ফলাফলটি ভিন্ন হবে) সমান: বিট-ওয়াইজ সমতা ==: বিট-ওয়াইজ সমতা

আরও ব্যাখ্যা জন্য এখানে দেখুন ।


অবজেক্ট.একোয়ালগুলি অগত্যা বিটওয়াইয়া সমতা দেখায় না। এটি ভার্চুয়াল পদ্ধতি এবং একটি ওভাররাইড যা খুশি তা করতে পারে।
ফোগ

হ্যাঁ, আপনি ঠিক বলেছেন, আপনি এটিকে ওভাররাইড করতে চাইলে যা করতে পারেন। তবে আমরা যে বিষয়ের সাথে কথা বলছি তা হ'ল ডিফল্ট বাস্তবায়ন। অবজেক্টের পূর্বনির্ধারিত বাস্তবায়ন quকুয়ালগুলি বিট-বুদ্ধিমান সমতা।
উইল ইউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.