5

Visual Studio 2008 (C#) での作業... List コレクションを使用して、カスタム クラス (Shift) のインスタンスを格納します。

Remove メソッドを使用して、特定のシフトをリストから削除したいと考えています。

ただし、 List.Remove() は常に最初に見つかったアイテムを削除します。

Shift に IComparable インターフェイスを実装しました。これで十分だと思い、IEqualityComparer の実装を追加しましたが、まだ効果がありません。

これが私の実装の抜粋です。

リージョンI比較メンバー

    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);
    }

エンドリージョン

regionIEqualityComparer メンバー

    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();
    }

エンドリージョン

それでも、リストに 2 つのシフトが含まれている場合は、「8:00 - 15:00」と言います。"12:00 - 16:00"、Remove("12:00-16:00") を呼び出すと、"8:00 - 15:00" が削除され、後者はコレクションに残ります!

ここで何が問題なのですか?どうも

4

4 に答える 4

10

上書きすることができ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)

于 2009-09-16T18:07:23.907 に答える
4

IComparableは通常、等しいかどうかを比較するために使用されない (順序付けに使用される) ため、List<T>.Remove()無視されます。

IEqualityComparerIComparableは、平等の目的では同等ではありません。これは、比較オブジェクト、つまり、他のオブジェクトが等しいかどうかを比較するオブジェクトによって実装されることになっています。等値比較をクラスに固有のものにしたい場合は、むしろ実装する必要がありますIEquatable<T>。または、インターフェイスを実装せずに、クラスをObject.Equals()オーバーライドするだけです。Object.GetHashCode()

于 2009-09-16T18:14:10.633 に答える
1

Remove はEqualityComparer<T>.Default、等価性を判断し、除去するオブジェクトを選択するために使用しますIEquatable<T>。これは、オブジェクトに実装されている場合に使用されます。それ以外の場合は、参照の等価性が使用されます。

必要な動作を得るには、次の 2 つのオプションがあります。

1) Shift を実装するIEquatable<T> (Object.Equals をオーバーライドするか、メソッドを作成するだけでなく、 Shift - を作成するShift : IEquatable<Shift>)

2) 使用List<T>.RemoveAt

于 2009-09-16T18:09:10.500 に答える
0

あなたが提供した例では、あなたは呼び出しています:

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

"12:00 - 16:00"この場合、 はString値であり、実際のShiftオブジェクトではありません。CompareToメソッドで、コードがString値をShiftオブジェクトに適切にキャストしていることを確認してください。そうしないと、開始時刻を比較すると...事態が混乱する可能性があります。

于 2009-09-16T18:13:57.840 に答える