32 Stimmen

Nachteile der Verlängerungsmethoden?

Die Erweiterungsmethode ist eine wirklich hilfreiche Funktion, mit der Sie viele Funktionen in jeder Klasse hinzufügen können. Aber ich frage mich, ob es einen Nachteil gibt, der mir Probleme bereiten könnte. Irgendwelche Kommentare oder Vorschläge?

40voto

Jon Skeet Punkte 1325502
  • Die Art und Weise, wie Erweiterungsmethoden importiert werden (d. h. ein ganzer Namespace auf einmal), ist nicht granular. Man kann nicht eine Erweiterung aus einem Namespace importieren, ohne den ganzen Rest zu erhalten.
  • Aus dem Quellcode ist nicht sofort ersichtlich, wo die Methode definiert ist. Dies ist auch ein Vorteil - Das bedeutet, dass Sie Ihren Code konsistent mit den übrigen Methoden des Typs gestalten können, selbst wenn Sie ihn aus irgendeinem Grund nicht an derselben Stelle platzieren können. Mit anderen Worten: Der Code ist auf hohem Niveau einfacher zu verstehen, aber komplizierter in Bezug auf die genau was gerade ausgeführt wird. Ich würde argumentieren, dies ist wahr von LINQ im Allgemeinen, auch.
  • Sie können nur Erweiterungsmethoden haben, keine Eigenschaften, Indexer, Operatoren, Konstruktoren usw.
  • Wenn Sie eine Klasse eines Drittanbieters erweitern und in einer späteren Version eine neue Methode mit der gleichen Signatur einführen, werden Sie nicht ohne weiteres erkennen, dass sich die Bedeutung Ihres aufrufenden Codes geändert hat. Wenn die neue Methode sehr ähnlich zu Ihrer Erweiterung, aber mit subtil unterschiedlichen Randbedingungen (oder was auch immer), dann könnte dies zu einigen sehr kniffligen Fehlern führen. Es ist aber relativ unwahrscheinlich, dass das passiert.

0 Stimmen

Großartige Erklärung. Ist Erweiterung Methoden schädlich in solchen Szenarien, wenn Aufruf durch mehrere Benutzer zur gleichen Zeit. wie ich eine Erweiterung Methode haben public static A ToDTO(this AD ad) { return AutoMapper.Mapper.Map<A>(ad); } und ich rufe folgendermaßen an AD.ToDTO() - seine Arbeit gut, wenn mit durch einzelne Benutzer, aber seine app stecken auf diese Methode, wenn von mehreren Benutzern aufgerufen und nach irgendwann werfen Timeout-Ausnahme, ist es Art von Nachteil der Erweiterung Methoden, wie wir eine statische Klasse hier haben.

1 Stimmen

@GauravKumarArora: Die Tatsache, dass etwas eine Erweiterungsmethode ist, ist dafür irrelevant - wenn es als normale statische Methode sicher wäre, die im "alten Stil" aufgerufen wird, dann ist es als Erweiterungsmethode sicher. Unter der Annahme, dass Sie mit "mehrere Benutzer" wirklich über Thread-Sicherheit sprechen, bieten Erweiterungsmethoden weder eine Art von Thread-Sicherheit noch entfernen sie diese.

1 Stimmen

Wir können die Erweiterungsmethode während des Unit-Tests nicht nachbilden.

6voto

Buu Nguyen Punkte 48055

Ein paar Dinge:

  • Es ist nicht immer klar, woher die Erweiterungsmethode kommt, es sei denn, Sie befinden sich in VS.NET
  • Erweiterungsmethoden können nicht über Reflection oder das dynamische Lookup von C# 4.0 aufgelöst werden

1 Stimmen

Sie können Erweiterungsmethoden über Reflection finden. Suchen Sie nach dem Attribut 'ExtensionAttribute'. Werfen Sie einen Blick auf stackoverflow.com/questions/299515/

0 Stimmen

@Patrik - aber man kann es nicht eindeutig tun, da man nicht weiß, welche "Verwendungen" berücksichtigt werden sollen. Manchmal ist es wichtig.

1 Stimmen

@Patrik: Was ich mit "Auflösung" meinte, war: Sie können zwar myType.extendedMethod() aufrufen, aber nicht über den üblichen Reflection-Code, d.h. typeof(MyType).GetMethod("extendedMethod").Invoke(...), oder dynamisches Nachschlagen, d.h. dynamic myType = new MyType(); myType.extendedMethod();

4voto

Marc Gravell Punkte 970173
  • Die Null-Prüfung bei statischen Methoden ist anders. Nicht unbedingt besser oder schlechter - aber anders, und der Entwickler muss das verstehen. Die Möglichkeit, eine Methode mit einem Nullwert aufzurufen, kann unerwartet sein und (manchmal) sehr nützlich sein.

  • Kein Polymorphismus (obwohl Überladung unterstützt wird)

  • Man kann in ein Chaos mit Mehrdeutigkeit geraten, wenn zwei Erweiterungsmethoden für den Quelltyp in Konflikt stehen (und keine davon als "besser" eingestuft wird). Der Compiler weigert sich dann, eine von beiden zu verwenden... was bedeutet, dass das Hinzufügen einer Erweiterungsmethode in Assembler A unverbundenen Code in Assembler B zerstören kann*.

  • Sie können in nicht mit C# 2.0 verwenden, wenn Sie also eine Bibliothek für C# 2.0 schreiben, ist es nicht hilfreich

  • Es braucht [ExtensionAttribute] - wenn Sie also eine Bibliothek für .NET 2.0 schreiben, geraten Sie in eine Zwickmühle: wenn Sie Ihre eigene [ExtensionAttribute], kann es zu Konflikten mit einem .NET 3.5-Aufrufer kommen

Verstehen Sie mich aber nicht falsch - ich bin ein großer Fan!

Sie können sich wahrscheinlich denken, dass ich gerade eine Bibliothek schreibe, die für C# 2.0 und .NET 2.0-Aufrufer funktionieren muss - und bei der (ärgerlicherweise) Erweiterungsmethoden sehr, sehr nützlich wären!

*=nur für den Compiler; Code, der bereits kompiliert wurde, ist in Ordnung

0 Stimmen

Obwohl Erweiterungsmethodenaufrufe nicht polymorph abgewickelt werden können, können Erweiterungsmethoden verschiedene Mittel verwenden, um ihre Aktion je nach den Typen, mit denen sie aufgerufen werden, zu variieren. Zum Beispiel könnte man eine SafeEquals<T,U>(this T it, U other) Erweiterungsmethode, die eine Func<T,U,bool> gespeichert in SafeComparer<T,U>.CheckEquality(it, other) (der Standard-Delegierte würde prüfen T y U und bestimmen, wie der Vergleich durchgeführt werden soll].

3voto

Lance Fisher Punkte 25464

Erweiterungsmethoden machen Spaß, aber sie können auch Probleme mit sich bringen. Was passiert zum Beispiel, wenn Sie eine Erweiterungsmethode schreiben und eine andere Bibliothek eine Erweiterungsmethode mit der gleichen Signatur erstellt? Dann werden Sie Schwierigkeiten haben, beide Namensräume zu verwenden.

Man kann auch argumentieren, dass sie weniger auffindbar sind. Ich denke, es kommt darauf an. In einigen Fällen sollte Ihr Code in einer Klasse verpackt werden, in anderen Fällen ist es in Ordnung, diese Funktionalität als Erweiterungsmethode hinzuzufügen.

In der Regel mache ich Erweiterungsmethoden als Wrapper für meine eigenen Klassen oder BCL-Klassen und lege sie in einen anderen Namensraum, z.B. Utils und Utils.Extensions. Auf diese Weise müssen die Erweiterungen nicht verwendet werden.

1 Stimmen

@ die Bemerkung zu den doppelten Unterschriften: Das ist auch in vielen anderen Sprachen ein inhärentes Risiko, und die Leute kommen gut damit zurecht. Obwohl es immer noch ein Nachteil sein kann, ist er in den meisten Fällen unwahrscheinlich, IMO.

0voto

1800 INFORMATION Punkte 125009

Was die Nachteile anbelangt, so würde ich sie ähnlich wie Makros sehen - es kann sein, dass der Code schwieriger zu warten ist, weil andere mit den von Ihnen hinzugefügten Erweiterungen nicht vertraut sind.

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