Frage

Werfen Sie einen Blick auf diese Klasse:

public class MemorialPoint:IMemorialPoint,IEqualityComparer<MemorialPoint>
{
    private string _PointName;
    private IPoint _PointLocation;
    private MemorialPointType _PointType;

    private DateTime _PointStartTime;
    private DateTime _PointFinishTime;

    private string _NeighborName;

    private double _Rms;
    private double _PointPdop;
    private double _PointHdop;
    private double _PointVdop;

    // getters and setters omitted

    public bool Equals(MemorialPoint x, MemorialPoint y)
    {
        if (x.PointName == y.PointName)
            return true;
        else if (x.PointName == y.PointName && x.PointLocation.X == y.PointLocation.X && x.PointLocation.Y == y.PointLocation.Y)
            return true;
        else
            return false;
    }

    public int GetHashCode(MemorialPoint obj)
    {
        return (obj.PointLocation.X.ToString() + obj.PointLocation.Y.ToString() + obj.PointName).GetHashCode();
    }
}

Ich habe auch eine Vector-Klasse, die lediglich zwei Punkte und einige andere atributes. Ich will nicht gleich Punkte in meinem Vektor haben, so dass ich mit dieser Methode kam:

public void RecalculateVector(IMemorialPoint fromPoint, IMemorialPoint toPoint, int partIndex)
        {
            if (fromPoint.Equals(toPoint))
                throw new ArgumentException(Messages.VectorWithEqualPoints);

            this.FromPoint = FromPoint;
            this.ToPoint = ToPoint;
            this.PartIndex = partIndex;

            // the constructDifference method has a weird way of working:
            // difference of Point1 and Point 2, so point2 > point1 is the direction
            IVector3D vector = new Vector3DClass();
            vector.ConstructDifference(toPoint.PointLocation, fromPoint.PointLocation);

            this.Azimuth = MathUtilities.RadiansToDegrees(vector.Azimuth);

            IPointCollection pointCollection = new PolylineClass();
            pointCollection.AddPoint(fromPoint.PointLocation, ref _missing, ref _missing);
            pointCollection.AddPoint(toPoint.PointLocation, ref _missing, ref _missing);

            this._ResultingPolyline = pointCollection as IPolyline;
        }

Und dieses Gerät zu testen, die mir eine Ausnahme geben soll:

    [TestMethod]
    [ExpectedException(typeof(ArgumentException), Messages.VectorWithEqualPoints)]
    public void TestMemoriaVector_EqualPoints()
    {
        IPoint p1 = PointPolygonBuilder.BuildPoint(0, 0);
        IPoint p2 = PointPolygonBuilder.BuildPoint(0, 0);

        IMemorialPoint mPoint1 = new MemorialPoint("teste1", p1);
        IMemorialPoint mPoint2 = new MemorialPoint("teste1", p2);

        Console.WriteLine(mPoint1.GetHashCode().ToString());
        Console.WriteLine(mPoint2.GetHashCode().ToString());

        vector = new MemorialVector(mPoint1, mPoint1, 0);
    }

Wenn ich den gleichen Punkt, das heißt, mPoint1, wie es in dem Code die Ausnahme ausgelöst wird. Als ich mPoint2 verwenden, auch ihren Namen und Koordinaten gleich sind, wird die Ausnahme nicht geworfen. Ich überprüfte ihren Hash-Codes, und sie sind in der Tat anders. Basierend auf dem Code, den ich in GetHashCode erstellt, tought ich diese zwei Punkte denselben Hash-Code haben.

Kann mir jemand erklären, warum dies nicht funktioniert, wie ich es würde tought? Ich bin nicht sicher, erklärte ich das gut, aber .. Ich schätze die Hilfe: D

George

War es hilfreich?

Lösung

Sie Implementierung IEqualityComparer<T> innerhalb der Art zu vergleichen, es versucht - was sehr seltsam ist. Sie sollten mit ziemlicher Sicherheit nur IEquatable<T> Implementierung und zwingenden Equals(object) statt. Das wäre auf jeden Fall Ihre Unit-Test-Arbeit machen.

Der Unterschied zwischen IEquatable<T> und IEqualityComparer<T> ist, dass erstere durch eine Klasse implementiert ist zu sagen: „Ich vergleiche können ich mit einer anderen Instanz des gleichen Typs.“ (Es ist nicht wird die gleiche Art sein, aber es ist in der Regel). Dies ist angezeigt, wenn es ein natürlicher Vergleich - zum Beispiel des Vergleich von string gewählten Ordnungs Gleichheit - es muss sein genau die gleiche Sequenz von char Werten.

Jetzt IEqualityComparer<T> ist anders - es keine zwei Instanzen eines Typs vergleichen. Es können mehrere verschiedene Implementierungen von dieser für einen bestimmten Typ sein, so spielt es keine Rolle, ob ein besonderer Vergleich ist die „natürliche“ - es ist jetzt noch die richtige für Ihren Job sein. So zum Beispiel, könnten Sie eine Shape Klasse haben und unterschiedliche Gleichheit comparers vergleichen Formen von Farbe, Fläche oder so ähnlich.

Andere Tipps

Sie müssen Object.Equals auch außer Kraft zu setzen.

Fügen Sie diese auf Ihre Implementierung:

// In MemorialPoint:
public override bool Equals(object obj)
{
    if (obj == null || GetType() != obj.GetType()) 
         return false;

    MemorialPoint y = obj as MemorialPoint;

    if (this.PointName == y.PointName)
        return true;
    else if (this.PointName == y.PointName && this.PointLocation.X == y.PointLocation.X && this.PointLocation.Y == y.PointLocation.Y)
        return true;
    else
        return false;
}

Ich würde dann andere Implementierung überarbeite die ersten zu verwenden und zusätzlich die entsprechenden null Kontrollen hinzuzufügen.

public bool Equals(MemorialPoint x, MemorialPoint y)
{
    if (x == null)
        return (y == null);
    return x.Equals(y);
}

Sie müssen auch Ihr Konzept der „Gleichheit“ zu überdenken, da es nicht zur Zeit der Sitzung .NET Rahmen Anforderungen .

Wenn möglich, ich ein Re-Design mit einem Repository von Gedenkpunktobjekten empfehlen (möglicherweise nach Name eingegeben), so dass eine einfache Referenz Gleichheit verwendet werden kann.

Sie haben einen ArcObjects-Tag auf das setzen, so dass ich nur dachte ich schon erwähnt, würde IRelationalOperator.Equals . Ich habe noch nie, ob diese Methode, um zu sehen getestet, um die Cluster-Toleranz der Geometrien Raumbezug ehrt. Dies kann mit Hilfe eingestellt werden ISpatialReferenceTolerance.XYTolerance .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top