Laden...

Listen comparen mit Except

Erstellt von w1z4rd2003 vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.142 Views
w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren
Listen comparen mit Except

Hallo zusammen,

An für sich muss ich eine simple sache machen und zwar will ich zwei listen comparen wie in diesem schönen Beispiel in der MSDN


            double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
            double[] numbers2 = { 2.2 };

            IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);

            foreach (double number in onlyInFirstSet)
                Console.WriteLine(number);

            /*
             This code produces the following output:

             2
             2.1
             2.3
             2.4
             2.5
            */

In meinem Fall verhält sich das ganze ein wenig anders, ich hab zwei Listen vom Typ <Application>. Application ist ein Objekt mit Eigenschaften wie Name, Number usw.

Als Ausgangslage hab ich zwei Listne die gefüllt sind mit diesen Applikationen, die eine heisst applications (mit 128 Objekten) und die andere heisst baseKitApplications (mit 47 Objekte). Die Einträge in der baseKitApplications sind alle auch in den anderen 128 enthalten, mit Except möchte ich jetzt die Differenz-Menge auslesen.

Damit das auch richtig funktionieren müsste hab ich in meiner Application Klasse folgende Methoden überschrieben


/// Funktion für die Gleichheitsprüfung </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(Application other)
        {
            if (Name == other.Name && Number == other.Number)
                return true;

            return false;
        }

        /// <summary>
        /// Überschreibt die Funktion Equals für die Gleichheitsprüfung </summary>
        public override bool Equals(Object obj)
        {
            if (obj == null) return base.Equals(obj);

            if (!(obj is Application))
                throw new InvalidCastException("The 'obj' argument is not a Application object.");

            return Equals(obj as Application);
        }

        /// <summary>
        /// Überschreibt die Funktion für die Erstellung des HashCode einer Application Instanz </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            string valueToHash = Name + Number;
            return valueToHash.GetHashCode();
        }

        /// <summary>
        /// Gleichheitsoperator </summary>
        public static bool operator ==(Application applicationOne, Application applicationTwo)
        {
            if (ReferenceEquals(null, applicationOne)) return ReferenceEquals(null, applicationTwo);
            if (ReferenceEquals(null, applicationTwo)) return false;

            return applicationOne.Equals(applicationTwo);
        }

        /// <summary>
        /// Ungleichheitsoperator </summary>
        public static bool operator !=(Application applicationOne, Application applicationTwo)
        {
            if (ReferenceEquals(null, applicationOne)) return !ReferenceEquals(null, applicationTwo);
            if (ReferenceEquals(null, applicationTwo)) return true;

            return (!applicationOne.Equals(applicationTwo));
        }

Und jetzt das Problem: wenn

IEnumerable<Application> except = applications.Except(baseKitApplications);

ausgeführt wird bekomme ich alle 128 Objekte zurück, anstelle von 128-47. Die überprüfung basiert laut meiner Equals Methode auf Name und Number, in beiden Fällen werden diese Werte korrekt abgefüllt.

Sieht jemand hier den fehler?

Gruss und vielen Dank
w1z4rd

795 Beiträge seit 2006
vor 13 Jahren

Versuch mal deinen eigenen EqualityComparer (ApplicationComparer) zu schreiben und dann applications.Except(baseKitApplications, new ApplicationComparer()) zu schreiben. Vielleicht hilft das ja.

Gruß, Christian.

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
5.742 Beiträge seit 2007
vor 13 Jahren

Hallo w1z4rd2003,

funktioniert denn die Equals Methode auch?
Teste das mal mit ein paar Beispieldaten.

Debugge den Code doch mal - werden die Equals-Methoden überhaupt aufgerufen?
Geben sie evtl. immer false zurück?

BTW: Deine Implementierung von Equals ist nicht wirklich optimal. Eine Exception sollte z.B. nicht geworfen werden.

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

darüberhinaus ist die Exception im Equals auch völlig überflüssig.
Ich kann mir überhaupt nicht vorstellen, warum man eine InvalidCastException selbst werfen sollte. Das ist nur verwirrend.
Entweder man versucht zu casten, und wenn's schief geht fliegt die Exception automatisch.
Oder man prüft mit is oder as, und behandelt entsprechend, dann braucht man auch nicht werfen.

Btw.:
is und as zusammen braucht man eigentlich auch nie, da muss gleich zweimal der Typ geprüft werden. Besser ist in solchen Fällen, nur as zu verwenden und anschließend auf null zu überprüfen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

82 Beiträge seit 2009
vor 13 Jahren

Zumal es sinniger wäre, wenn das Objekt keine Application ist, einfach false zurückzugeben, denn dann ist ja auch keine Gleichheit gegeben. Und darauf wird ja geprüft. Sprich die Antwort auf die Frage "Ist obj gleich Application XYZ?" wird doch mit true oder false immer vollständig beantwortet.

Diskordianer schwimmen nicht gegen den Strom - sie klettern aus dem Fluss! Ein Mathematiker ist ein Mensch, der einen ihm vorgetragenen Gedanken nicht nur sofort versteht, sondern auch weiß auf welchem Denkfehler er beruht
w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Vielen Dank für Eure Hilfe,

Mittlerweile hab ich es zum laufen gebracht! 🙂

Gruss
w1z4rd