سؤال

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

لنقم بإنشاء مثال افتراضي.أنا أكتب تطبيقًا يستخدم Twitter API، وهو يحتوي على سقسقة فئة تحتوي على جميع خصائص التغريدة الواحدة:النص والمرسل والتاريخ والوقت والمصدر وما إلى ذلك.إذا كنت أرغب في مقارنة كائنات الفصل سقسقة من أجل التكافؤ، هل يمكنني فقط استخدام:

Tweet a, b;
if (a == b)
{
//do something...
}

هل هذا التحقق من تكافؤ جميع الخصائص التابع سقسقة الطبقة بين أ و ب?

ان لم، سيكون النهج الصحيح هو التحميل الزائد على == المشغل أو العامل للتحقق بوضوح من تكافؤ جميع المجالات؟

تحديث: من الإجابتين الأوليين، هل أنا على حق في الافتراض:

  • إذا == المشغل أو يساوي لم يتم تحميل الأسلوب بشكل زائد لفئة، و == عامل ل هدف يتم استخدام الطبقة.
  • ال == عامل ل هدف يتحقق الفصل من المساواة في موقع الذاكرة.
  • لا بد لي من التحميل الزائد == المشغل أو يساوي طريقة إنجاز هذه المهمة.
  • في حالة التحميل الزائد، لا بد لي من التحقق من التكافؤ في الخصائص يدويًا، لذلك ولا توجد طريقة للقيام بذلك بشكل شبه تلقائي، على سبيل المثال، في حلقة, ، يمين؟

التحديث رقم 2: أدلى يوري بتعليق مفاده أنه من الممكن التحقق من التكافؤ في الخصائص في == عامل مع انعكاس.كيف يمكن القيام بذلك؟هل يمكن أن تعطيني بعض التعليمات البرمجية عينة؟شكرًا!

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

المحلول

MSDN لديه جيدة مثال كيفية القيام بذلك:

   public override bool Equals(object o) 
   {
      try 
      {
         return (bool) (this == (DBBool) o);
      }
      catch 
      {
         return false;
      }
   }

ثم تقوم بتحميل == و !=:

// Equality operator. Returns dbNull if either operand is dbNull, 
   // otherwise returns dbTrue or dbFalse:
   public static DBBool operator ==(DBBool x, DBBool y) 
   {
      if (x.value == 0 || y.value == 0) return dbNull;
      return x.value == y.value? dbTrue: dbFalse;
   }

   // Inequality operator. Returns dbNull if either operand is
   // dbNull, otherwise returns dbTrue or dbFalse:
   public static DBBool operator !=(DBBool x, DBBool y) 
   {
      if (x.value == 0 || y.value == 0) return dbNull;
      return x.value != y.value? dbTrue: dbFalse;
   }

ولا تنسَ التحميل الزائد على طريقة GetHash.

يحرر:

لقد كتبت العينة السريعة التالية لاستخدام الانعكاس في المقارنة.يجب أن يكون هذا أكثر شمولاً، وقد أحاول إنشاء مدونة عنه إذا أراد الناس مني أن:

public class TestEquals
{
    private int _x;
    public TestEquals(int x)
    {
        this._x = x;
    }

    public override bool Equals(object obj)
    {
        TestEquals te = (TestEquals)obj;
        if (te == null) return false;

        foreach (var field in typeof(TestEquals)
            .GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (!field.GetValue(this).Equals(field.GetValue(te)))
                return false;
        }
        return true;
    }
}

نصائح أخرى

بالنسبة لأنواع المراجع، فإن التطبيقات الافتراضية لكل من == المشغل و Equals() ستتحقق الطريقة ببساطة من أن كلا الكائنين لهما نفس المرجع، وبالتالي هما نفس المثيل.

إذا كنت تريد التحقق من تساوي محتويات كائنين مختلفين، فيجب عليك كتابة الكود للقيام بذلك بنفسك، بطريقة أو بأخرى.سيكون من الممكن القيام به مع التفكير ( مبيونيت إطار عمل الاختبار يفعل شيئًا على هذا المنوال) ولكن مع عقوبة أداء ثقيلة وفرصة جيدة أنه لن يفعل تمامًا ما توقعته على أي حال، ويجب عليك تنفيذه == أو Equals و GetHashCode باليد.

الطريقة الصحيحة هي التحميل الزائد لطريقة يساوي لفئة التغريدة بالإضافة إلى عامل التشغيل ==، كما هو موضح هنا.

هل سيؤدي ذلك إلى التحقق من تكافؤ جميع خصائص فئة التغريدة بين a وb؟

لا

إذا لم يكن الأمر كذلك، فهل سيكون النهج الصحيح هو زيادة تحميل عامل التشغيل == للتحقق بشكل صريح من تكافؤ جميع الحقول؟

يمكنك إما التحميل الزائد على == المشغل، أو التحميل الزائد يساوي وظيفة.

يحرر

أعطىYuriy مثالاً جيدًا لمطابقة جميع المتغيرات غير العامة.وبما أنني كتبت أيضًا مثالاً، فها هو (يقارن الخصائص)

class TwitterItem
{
    private string myValue = "default value";
    public string Value1
    {
        get { return myValue; }
        set { myValue = value; }
    }
    public string Value2
    {
        get { return myValue; }
        set { myValue = value; }
    }
    public string Value3
    {
        get { return myValue; }
        set { myValue = value; }
    }

    public override bool Equals(object obj)
    {
        if (base.Equals(obj)) return true;

        Type type = typeof(TwitterItem);
        PropertyInfo[] properties = type.GetProperties();

        foreach (PropertyInfo property in properties)
        {
            if (false == property.GetValue(this, null).Equals(property.GetValue(obj, null)))
                return false;
        }

        return true;
    }
}

يمكنك مقارنة الخصائص باستخدام الانعكاس:

var a = new Entity() { Name = "test", ID = "1" };
var b = new Entity() { Name = "test", ID = "1" };
var c = new Entity() { Name = "test", ID = "2" };
System.Diagnostics.Debug.WriteLine(a.Equals(b));//Returns true
System.Diagnostics.Debug.WriteLine(a.Equals(c));//Returns false


public class Entity
{
    public string Name { get; set; }
    public string ID { get; set; }
    public override bool Equals(object obj)
    {
        var t = obj.GetType();
        foreach (var p in t.GetProperties())
        {
            if (t.GetProperty(p.Name).GetValue(obj, null) != t.GetProperty(p.Name).GetValue(this, null))
                return false;
        }
        return true;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top