سؤال

العمل في Visual Studio 2008 (C #) ... يمكنني استخدام مجموعة قائمة لتخزين مثيلات فئة مخصصة بلدي (التحول).

وأريد حذف تحول معين من القائمة باستخدام أسلوب إزالة.

ولكن List.Remove () يحذف دائما العنصر الأول يجدها.

، ثم اضاف

ولقد نفذت واجهة IComparable لبلدي التحول، اعتقدت أن هذا سيكون كافيا لي تنفيذ IEqualityComparer، وأنها لا تزال لديها أي تأثير.

وفيما يلي مقتطفات مع تنفيذ بلدي:

<اقتباس فقرة>   

والمنطقة IComparable الأعضاء

    public int CompareTo(object obj)
    {
        Shift s1 = this;
        Shift s2 = (Shift)obj;
        if (s1.start.time != s2.start.time)
            return s1.start.CompareTo(s2.start);
        else
            return s1.end.CompareTo(s2.end);
    }
     

وendregion

     

والمنطقة IEqualityComparer الأعضاء

    public bool Equals(Shift x, Shift y)
    {

        if ((x.opening) != (y.opening)) return false;
        if ((x.closing) != (y.closing)) return false;
        if (!x.opening) if (x._start != y._start) return false;
        if (!x.closing) if (x._end != y._end) return false;
        if (x.when != y.when) return false;
        if (x.day != y.day) return false;
        if (x.EmployeeID != y.EmployeeID) return false;
        return true;
    }

    public int GetHashCode(Shift obj)
    {
        return obj.ToString().ToLower().GetHashCode();
    }
     

وendregion

وبعد، لا يزال - عندما تحتوي قائمة فترتين، ويقول "8:00 حتي 15:00". "12:00 حتي 16:00"، داعيا إزالة ( "12: 00-16: 00")! النتائج في "8:00 حتي 15:00" الحصول على إزالتها، ويبقى واحد الأخير في المجموعة

ما هو الخطأ هنا؟ تشك

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

المحلول

ويمكنك تجاوز object.GetHashCode وobject.Equals:

public override bool Equals(object obj)
{
    if(obj == null)
    {
        return false;
    }
    return Equals(this, obj as Shift);
}

public override int GetHashCode()
{
    return this.GetHashCode(this);
}

ويجب عليك أيضا ربما القيام فحص لاغية في Equals(x, y).

نصائح أخرى

لا تستخدم IComparable عادة لمقارنة من أجل المساواة (انها تستخدم للترتيب)، بحيث يتجاهل List<T>.Remove() ذلك.

وIEqualityComparer ليس ما يعادل IComparable لأغراض المساواة. ومن المفترض أن يتم تنفيذها من قبل الكائن المقارن - أي كائن أن يقارن <م> غيرها من الأشياء من أجل المساواة. إذا كنت تريد مقارنات المساواة لتكون الأصيل في صفك، فإنك بدلا تحتاج إلى تنفيذ IEquatable<T>. أو مجرد تجاوز Object.Equals() وObject.GetHashCode() في صفك، دون تنفيذ أية واجهات.

وإزالة تستخدم EqualityComparer<T>.Default لتحديد المساواة واختيار أي اعتراض على إزالة، والتي سوف تستخدم IEquatable<T> إذا لم تنفذ على وجوه الخاص بك، وإلا، فإنه سيتم استخدام المساواة المرجعية.

ولديك خياران للحصول على السلوك الذي تريده:

1) جعل التحول تنفيذ IEquatable<T> (وليس فقط تجاوز كائن .Equals أو جعل الأسلوب، ولكن جعل التحول - Shift : IEquatable<Shift>)

2) استخدام List<T>.RemoveAt

ومع المثال الذي قدمته، كنت أنت تدعو:

List<Shift>.Remove("12:00 - 16:00");

و"12:00 - 16:00" في هذه الحالة، هو قيمة String وليس كائن Shift الفعلي. تأكد من أن في طريقة CompareTo بك ان كنت الكود هو صحيح الصب قيمة String إلى كائن Shift. خلاف ذلك، عندما يقارن بدء مرات ... أشياء يمكن صوابه.

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