سؤال

لدي شرط في تطبيق silverlight أن يقارن 2 سلاسل, لسبب ما عندما استخدم == فإنه يعود كاذبة في حين .Equals() يعود صحيح.

هنا هو رمز:

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

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

أي سبب لماذا يحدث هذا ؟

هل كانت مفيدة؟

المحلول

عندما == يستخدم على تعبير من نوع object, سوف حل System.Object.ReferenceEquals.

Equals هو مجرد virtual طريقة ويتصرف على هذا النحو ، حتى تجاوز الإصدار سيتم استخدامها (الذي ، string نوع يقارن محتويات).

نصائح أخرى

عند مقارنة مرجع كائن إلى سلسلة (حتى لو كان مرجع كائن يشير إلى سلسلة) ، سلوك == مشغل محددة إلى فئة سلسلة تجاهلها.

عادة (عندما لا نتعامل مع سلاسل, هذا هو) ، 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

== و .Equals كلاهما يعتمد على سلوك محدد في النوع و النوع الفعلي في الموقع.على حد سواء هي مجرد طرق / مشغلي التي يمكن تجاوزها في أي نوع و أي سلوك المؤلف رغب في ذلك.في تجربتي, أجد أنه من الشائع للناس أن تنفيذ .Equals على كائن ولكن إهمال تنفيذ المشغل ==.وهذا يعني أن .Equals فعلا قياس المساواة بين القيم حين == سوف تقيس ما إذا كان أو لم تكن هي نفس المرجعية.

عندما كنت أعمل مع نوع جديد له تعريف في الجريان أو كتابة خوارزميات عامة ، أجد أفضل الممارسات التالية

  • إذا كنت ترغب في مقارنة المراجع في C#, أنا استخدم Object.ReferenceEquals مباشرة (لا حاجة في عامة الأحوال)
  • إذا كنت ترغب في مقارنة القيم يمكنني استخدام EqualityComparer<T>.Default

في بعض الحالات عندما أشعر استخدام == غامضة سوف تستخدم صراحة Object.Reference يساوي في قانون لإزالة الغموض.

إريك ليبرت فعلت مؤخرا بلوق وظيفة حول موضوع لماذا هناك 2 طرق المساواة في CLR.يستحق القراءة

أولا ، هو الفارق.عن أرقام

> 2 == 2.0
True

> 2.Equals(2.0)
False

و سلاسل

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

> x.Equals(null)
NullReferenceException

في كلتا الحالتين ، == يتصرف على نحو أكثر فائدة من .Equals

وأود أن أضيف أنه في حالة تحويل الكائن إلى سلسلة ثم أنها سوف تعمل بشكل صحيح.هذا هو السبب المترجم سوف تعطيك تحذيرا قائلا:

ممكن غير مقصودة مرجع المقارنة ؛ للحصول على قيمة المقارنة ، يلقي الجانب الأيسر إلى نوع 'سلسلة'

== المشغل 1.إذا كان من المعاملات هي أنواع القيم وقيمها متساوية ، إرجاع true آخر كاذبة.2.إذا كان من المعاملات هي أنواع المراجع مع استثناء من سلسلة كل من الرجوع إلى نفس الكائن ، إرجاع true آخر كاذبة.3.إذا كان من المعاملات هي نوع السلسلة ، القيم متساوية ، إرجاع true آخر كاذبة.

.يساوي 1.إذا كان من المعاملات هي أنواع المراجع ، فإنه ينفذ إشارة المساواة هذا إذا كان كل من الرجوع إلى نفس الكائن ، إرجاع true آخر كاذبة.2.إذا كان من المعاملات هي أنواع قيمة ثم وخلافا == مشغل فإنه يتحقق عن النوع الأول من أنواع هي نفس ينفذ == مشغل آخر تقوم بإرجاع false.

بقدر ما أفهم الجواب بسيط:

  1. == يقارن مراجع الكائنات.
  2. .يساوي يقارن كائن المحتوى.
  3. سلسلة أنواع البيانات تتصرف دائما مثل المحتوى المقارنة.

أتمنى الصحيح وأن أجبت على سؤالك.

لأن إصدار ثابت من .Equal طريقة لم يذكر حتى الآن وأود أن أضيف هنا أن ألخص ومقارنتها 3 الاختلافات.

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

حيث MyString هو المتغير الذي يأتي من مكان آخر في التعليمات البرمجية.

معلومات خلفية ، summerize:

في جافا باستخدام == مقارنة السلاسل لا ينبغي أن تستخدم.أنا أذكر هذا في حال كنت بحاجة إلى استخدام كل اللغات أيضا أن تعلم أن استخدام == كما يمكن استبدال شيء أفضل في C#.

في C# لا يوجد فرق عملي مقارنة السلاسل باستخدام الأسلوب 1 أو الطريقة 2 طالما كلاهما من نوع string.ومع ذلك ، إذا كان أحد باطل ، هو واحد من نوع آخر (مثل عدد صحيح) ، أو واحد يمثل كائن لديه مرجعية مختلفة, ثم السؤال الأولي يظهر قد تواجه هذا مقارنة محتوى المساواة قد لا يعود ما كنت تتوقع.

الحلول المقترحة:

لأن استخدام == ليس بالضبط نفس باستخدام .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.

أنا في حيرة قليلا هنا.إذا كان وقت التشغيل نوع المحتوى هو من نوع string ، ثم كلا == و يساوي أن العودة الحقيقية.ومع ذلك, لأن هذا لا يبدو أن يكون صحيحا ، ثم وقت التشغيل نوع المحتوى غير سلسلة الاتصال يساوي على ذلك هو القيام المرجعي المساواة و هذا يفسر لماذا يساوي("الطاقة الهجوم") فشل.ولكن في الحالة الثانية ، القرار على النحو الذي فوق طاقتها == ثابت المشغل يجب أن يسمى في وقت الترجمة و هذا القرار يبدو ==(string,string).هذا يوحي لي هذا المحتوى يوفر التحويل الضمني إلى سلسلة.

هناك بعد آخر رد سابق قبل @BlueMonkMN.البعد الإضافي هو أن الإجابة على @Drahcir عنوان السؤال كما جاء أيضا يعتمد على كيف وصلنا إلى 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

إضافة نقطة واحدة على الإجابة.

.EqualsTo() الأسلوب يتيح لك توفير لمقارنة ضد الثقافة القضية الحساسة.

فقط إضافة إلى إجابات جيدة:هذا السلوك لا يقتصر على سلاسل أو مقارنة مختلفة numbertypes.حتى إذا كان كل العناصر من نوع كائن من نفس الكامنة نوع."==" لا تعمل.

الصورة التالية تظهر نتائج المقارنة بين اثنين من كائن {int} - القيم

Example From VS2017

على == المميز في C# هو المساواة-التحقق من المشغلين.عندما مترجم لقاءات هذا المنطلق سوف تحقق ما إذا كان أي من أنواع يجري مقارنة نفذت المساواة-مشغل الزائد إما محددة الجمع بين النوعين مقارنة (*) أو مزيج من الأنواع التي كلا النوعين يمكن تحويلها.إذا كان المترجم يجد مثل هذا الحمل الزائد فإنه سيتم استخدامه.وإلا إذا كان هذين النوعين على حد سواء أنواع المراجع وهم لا علاقة الطبقات (إما قد يكون واجهة ، أو أنها قد تكون ذات صلة فئات), المترجم الصدد == كمرجع-عامل المقارنة.إذا لم يكن أي حالة ينطبق عليها تجميع سوف تفشل.

علما أن بعض اللغات الأخرى استخدام منفصلة الرموز اثنين المساواة-التحقق من المشغلين.في VB.NET ، على سبيل المثال ، = رمز يستخدم في التعبير فقط overloadable المساواة-التحقق من المشغل ، Is يستخدم كمرجع-اختبار أو فارغة اختبار المشغل.وهو استخدام = على نوع التي لا تجاوز المساواة-التحقق من المشغل سوف تفشل ، وكذلك محاولة استخدام Is لأي غرض بخلاف اختبار إشارة المساواة أو البطلان.

(*)أنواع عموما الزائد فقط المساواة للمقارنة مع أنفسهم ، ولكن قد يكون من المفيد أنواع الزائد المساواة بين المشغل للمقارنة مع غيرها من أنواع معينة;على سبيل المثال ، int يمكن أن يكون (IMHO ينبغي أن يكون ولكن لم) تعريف المساواة مشغلي مقارنة مع float, بحيث 16777217 لن التقرير نفسه يساوي 16777216f.كما هو لأن لا يوجد مثل هذا المشغل هو تعريف, C# تشجيع int إلى float, التقريب إلى 16777216f قبل المساواة-التحقق من المشغل يراها ؛ هذا المشغل ثم يرى اثنين تساوي أرقام الفاصلة العائمة و التقارير لهم على قدم المساواة ، علم التقريب التي وقعت.

عظيم حقا إجابات الأمثلة!

أود فقط أن أضيف الفرق الأساسي بين البلدين ،

شركات مثل == ليست متعددة الأشكال ، في حين Equals هو

مع هذا المفهوم في الاعتبار, إذا كنت تعمل أي مثال (من خلال النظر في اليد اليسرى واليد اليمنى نوع مرجع و التدقيق/معرفة إذا نوع في الواقع == مشغل طاقتها و يساوي يجري تنقضها) كنت على يقين من الحصول على الجواب الصحيح.

عندما نخلق أي كائن هناك قسمين إلى كائن واحد هو مضمون والآخر هو إشارة إلى هذا المحتوى.== يقارن بين كل من المحتوى المرجعية ؛ equals() يقارن فقط المحتوى

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

==

عامل التشغيل == يمكن استخدامها لمقارنة اثنين من المتغيرات من أي نوع ، ببساطة يقارن بت.

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

ملاحظة :هناك المزيد من الأصفار على الجانب الأيسر من الباحث ولكن نحن لا نهتم هنا.

الباحث (00000011) == بايت ب (00000011)

أتذكر == مشغل يهتم فقط حول نمط البتات في متغير.

استخدام == إذا مرجعين (الأوليات) يشير إلى نفس الكائن على كومة.

القواعد هي نفسها ما إذا كان المتغير هو إشارة أو البدائية.

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

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

أ = ج= هو صحيح a == b كاذبة

بت نمط هي نفسها a و c ، لذلك فهي متساوية باستخدام ==.

تساوي():

استخدام يساوي() طريقة لمعرفة إذا اثنين من كائنات مختلفة متساوية.

مثل مختلفين سلسلة الكائنات التي تمثل الشخصيات في "جين"

الفرق الوحيد بين متساوين == على نوع الكائن المقارنة.في حالات أخرى مثل الإشارة أنواع و أنواع قيمة ، فهي نفسها تقريبا(إما كلاهما بت الحكمة المساواة أو كلاهما إشارة المساواة).

وجوه:يساوي:بت الحكمة المساواة ==:إشارة المساواة

سلسلة:(يساوي == هي نفس السلسلة, ولكن إذا كان واحد من سلسلة تغيير وجوه ، ثم مقارنة النتيجة سوف تكون مختلفة) يساوي:بت الحكمة المساواة == :بت الحكمة المساواة

انظر هنا لمزيد من التوضيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top