12 Stimmen

Wann werden Erweiterungsmethoden unterbrochen?

Wir diskutieren gerade darüber, ob Erweiterungsmethoden in .NET schlecht sind oder nicht. Oder unter welchen Umständen Extension-Methoden schwer zu findende Bugs einführen oder sich auf andere Weise unerwartet verhalten können.

Wir haben uns das ausgedacht:

  • Das Schreiben einer Erweiterungsmethode für Typen, die nicht unter Ihrer Kontrolle stehen (z.B. die Erweiterung von DirectoryInfo mit GetTotalSize(), etc...) ist schlecht, weil der Besitzer der API eine Methode einführen könnte, die unsere Erweiterung versteckt - und möglicherweise andere Randfälle hat. Zum Beispiel wird das Testen auf null in einer Erweiterungsmethode automatisch in eine NullReferenceException übersetzen, wenn die Erweiterungsmethode aufgrund des Ausblendens nicht mehr verwendet wird.

Frage:

  • Gibt es noch andere gefährliche Situationen als "Verstecken", an die wir nicht denken?

Bearbeiten:

Eine weitere sehr gefährliche Situation. Angenommen, Sie haben eine Erweiterungsmethode:

namespace Example.ExtensionMethods
{
    public static class Extension
    {
        public static int Conflict(this TestMe obj)
        {
            return -1;
        }
    }
}

Und benutzen Sie es:

namespace Example.ExtensionMethods.Conflict.Test
{
    [TestFixture]
    public class ConflictExtensionTest
    {
        [Test]
        public void ConflictTest()
        {
            TestMe me = new TestMe();
            int result = me.Conflict();
            Assert.That(result, Is.EqualTo(-1));
        }
    }
}

Beachten Sie, dass der Namespace, in dem Sie ihn verwenden, länger ist.

Jetzt referenzieren Sie damit eine dll:

namespace Example.ExtensionMethods.Conflict
{
    public static class ConflictExtension
    {
        public static int Conflict(this TestMe obj)
        {
            return 1;
        }
    }
}

Und Ihr Test wird scheitern! Er wird kompiliert, ohne dass ein Compilerfehler auftritt. Er wird einfach scheitern . Ohne dass Sie überhaupt "using Example.ExtensionMethods.Conflict" angeben müssen. Der Compiler wird den Namespace-Namen durchsuchen und Example.ExtensionMethods.Conflict.ConflictExtension vor Example.ExtensionMethods.Extension finden und diese verwenden ohne sich jemals über zweideutige Erweiterungsmethoden zu beschweren . Oh, das Grauen!

0 Stimmen

Ich musste ein Beispiel für ein neues Mitglied ausprobieren, das eine Erweiterungsmethode versteckt, ohne dass der Compiler einen Pieps von sich gibt, bevor ich es glauben konnte! Ich denke, D hat das mit seinem Konzept der "Überladungssätze" richtig gemacht.

1voto

Joel Coehoorn Punkte 377088

Was in .Net als Erweiterungsmethoden bezeichnet wird, ist ebenfalls eine begrenzte Form einer MonkeyPatching (Versuchen Sie, den php-Rant da drin zu ignorieren).

Das sollte Ihnen etwas Stoff für Ihre Diskussion liefern.

1voto

Brian Rasmussen Punkte 112118

Zunächst einmal glaube ich, dass Ihre Formulierung ein wenig irreführend ist. Ich nehme an, Sie sprechen von "Typen" und nicht von "Objekten".

Zweitens besteht der große Vorteil von Erweiterungsmethoden darin, dass Sie einem Typ, den Sie nicht kontrollieren, Funktionen hinzufügen können. Wenn Sie den Typ kontrollieren, warum ändern Sie dann nicht einfach den Typ, anstatt sich auf Erweiterungsmethoden zu verlassen?

0 Stimmen

Danke für den Objekt -> Typ Geek Grammatikfehler. Die Vorteile sind wohl bekannt. Wir sind auf der Suche nach Gefahren.

1voto

AAT Punkte 3109

Wir haben in meinem Team die Haltung eingenommen, dass Erweiterungsmethoden so nützlich sind, dass man sie realistischerweise nicht verbieten kann, aber so gefährlich (vor allem wegen des Problems des Versteckens), dass man ein wenig vorsichtig sein muss. Daher haben wir beschlossen, dass alle Namen von Erweiterungsmethoden mit dem Präfix X (wir haben also eine Reihe von XInit...() Methoden, um z. B. Steuerelemente auf sinnvolle Weise zu initialisieren). Auf diese Weise wird a) die Wahrscheinlichkeit einer Namenskollision verringert und b) weiß der Programmierer, dass er eine Erweiterungsmethode und nicht eine Klassenmethode verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X