ما هو التطبيق الأساسي "الأفضل" لـ Equals() لأنواع المراجع؟

StackOverflow https://stackoverflow.com/questions/74514

  •  09-06-2019
  •  | 
  •  

سؤال

يعد تنفيذ Equals() لأنواع المراجع أصعب مما يبدو.تطبيقي الأساسي الحالي يسير على النحو التالي:

public bool Equals( MyClass obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null they are not equal because in C# this cannot be null.
  if( ReferenceEquals( obj, null ) )
   return false;

   // Compare data to evaluate equality    
   return _data.Equals( obj._data );
}

public override bool Equals( object obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null or is of a different types the objects are not equal. 
  if( ReferenceEquals( obj, null ) || obj.GetType() != GetType() )
    return false;

  // Use type-safe equality comparison
  return Equals( (MyClass)obj );
}

public override int GetHashCode()
{
  // Use data's hash code as our hashcode  
  return _data.GetHashCode();
}

أعتقد أن هذا يغطي جميع حالات الزاوية (الميراث وما شابه) ولكن قد أكون مخطئًا.ماذا تظنون يا جماعة؟

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

المحلول

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

http://gregbeech.com/blog/implementing-object-equality-in-dotnet

نصائح أخرى

من الأفضل ألا تكون this._data فارغة إذا كانت أيضًا نوعًا مرجعيًا.

public bool Equals( MyClass obj )
{
    if (obj == null) {
        return false;
    }
    else {
        return (this._data != null && this._data.Equals( obj._data ))
                         || obj._data == null;
    }
}

public override bool Equals( object obj )
{
    if (obj == null || !(obj is MyClass)) {
        return false;
    }
    else {
        return this.Equals( (MyClass)obj );
    }
}

public override int GetHashCode() {
    return this._data == null ? 0 : this._data.GetHashCode();
}

فيما يتعلق بالميراث، أعتقد أنه يجب عليك فقط ترك نموذج OO يقوم بسحره.

على وجه التحديد، GetType() يجب إزالة الاختيار، فقد يؤدي ذلك إلى كسر تعدد الأشكال.

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

شخصيا أستخدم ما يلي:

    public override bool Equals(object obj)
    {
        var other = obj as MyClass;
        if (other == null) return false;

        return this.data.Equals(other.data);
    }

يعتمد ذلك على ما إذا كنت تكتب نوع قيمة أو نوع مرجع.بالنسبة لنوع القيمة القابلة للفرز، أوصي بما يلي:مقتطف تعليمات برمجية لبرنامج Visual Studio 2005 الذي يقوم بتنفيذ نوع قيمة هيكلية يلتزم بإرشادات تصميم إطار العمل

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