Erweiterungsmethoden bieten nichts, was auf andere Weise nicht möglich ist. Sie sind syntaktischer Zucker, um die Entwicklung zu verbessern, ohne einen tatsächlichen technischen Nutzen zu bieten.
Erweiterungsmethoden sind relativ neu. Standards und Konventionen werden normalerweise von der Meinung der Bevölkerung festgelegt (plus langjähriger Erfahrung darüber, was letztendlich eine schlechte Idee ist), und ich glaube nicht, dass wir an dem Punkt angelangt sind, an dem wir eine endgültige Linie ziehen können, der alle zustimmen.
Ich kann jedoch mehrere Argumente sehen, die auf Dingen basieren, die ich von Kollegen gehört habe.
1. Sie ersetzen normalerweise statische Methoden.
Erweiterungsmethoden basieren am häufigsten auf Dingen, die sonst statische Methoden gewesen wären, nicht auf Klassenmethoden. Sie sehen aus wie Klassenmethoden, sind es aber nicht wirklich.
Erweiterungsmethoden sollten einfach nicht als Alternative für Klassenmethoden betrachtet werden. sondern um ansonsten syntaktisch hässlichen statischen Methoden ein "Klassenverfahren" zu verleihen .
2. Wenn Ihre beabsichtigte Methode spezifisch für ein konsumierendes Projekt ist, jedoch nicht für die Quellbibliothek.
Nur weil Sie sowohl die Bibliothek als auch den Verbraucher entwickeln, bedeutet dies nicht, dass Sie bereit sind, die Logik dort zu platzieren, wo sie passt.
Zum Beispiel:
- Sie haben eine
PersonDto
Klasse aus Ihrem DataLayer
Projekt.
- Ihr
WebUI
Projekt möchte a PersonDto
in a konvertieren können PersonViewModel
.
Sie können (und möchten) diese Konvertierungsmethode nicht zu Ihrem DataLayer
Projekt hinzufügen . Da diese Methode auf das WebUI
Projekt beschränkt ist, sollte sie sich in diesem Projekt befinden.
Mit einer Erweiterungsmethode können Sie diese Methode innerhalb Ihres Projekts (und möglicher Konsumenten Ihres Projekts) global zugänglich machen, ohne dass die DataLayer
Bibliothek sie implementieren muss.
3. Wenn Sie der Meinung sind, dass Datenklassen nur Daten enthalten sollten.
Beispielsweise Person
enthält Ihre Klasse die Eigenschaften für eine Person. Sie möchten jedoch einige Methoden haben, mit denen einige Daten formatiert werden können:
public class Person
{
//The properties...
public SecurityQuestionAnswers GetSecurityAnswers()
{
return new SecurityQuestionAnswers()
{
MothersMaidenName = this.Mother.MaidenName,
FirstPetsName = this.Pets.OrderbyDescending(x => x.Date).FirstOrDefault()?.Name
};
}
}
Ich habe viele Mitarbeiter gesehen, die die Idee hassen, Daten und Logik in einer Klasse zu mischen. Ich bin mit einfachen Dingen wie dem Formatieren von Daten nicht ganz einverstanden, aber ich gebe zu, dass es sich im obigen Beispiel schmutzig anfühlt Person
, wenn man sich darauf verlassen muss SecurityQuestionAnswers
.
Durch das Einfügen dieser Methode in eine Erweiterungsmethode wird verhindert, dass die ansonsten reine Datenklasse beschmutzt wird.
Beachten Sie, dass dieses Argument stilistisch ist. Dies ähnelt Teilklassen. Dies hat wenig bis gar keinen technischen Vorteil, aber Sie können Code in mehrere Dateien aufteilen, wenn Sie ihn für sauberer halten (z. B. wenn viele Benutzer die Klasse verwenden, sich aber nicht um Ihre zusätzlichen benutzerdefinierten Methoden kümmern).
4. Hilfsmethoden
In den meisten Projekten neige ich dazu, Helferklassen zu haben. Hierbei handelt es sich um statische Klassen, die normalerweise eine Sammlung von Methoden zur einfachen Formatierung bereitstellen.
Beispielsweise hatte eine Firma, bei der ich arbeitete, ein bestimmtes Datums- / Uhrzeitformat, das sie verwenden wollten. Anstatt die Formatzeichenfolge überall einzufügen oder die Formatzeichenfolge zu einer globalen Variablen zu machen, habe ich mich für eine DateTime-Erweiterungsmethode entschieden:
public static string ToCompanyFormat(this DateTime dt)
{
return dt.ToString("...");
}
Ist das besser als eine normale statische Hilfsmethode? Ich glaube schon. Es bereinigt die Syntax. Anstatt
DateTimeHelper.ToCompanyFormat(myObj.CreatedOn);
Ich könnte:
myObj.CreatedOn.ToCompanyFormat();
Dies ähnelt einer fließenden Version derselben Syntax. Ich mag es mehr, obwohl es keinen technischen Vorteil hat, wenn man übereinander steht.
Alle diese Argumente sind subjektiv. Keiner von ihnen deckt einen Fall ab, der sonst niemals abgedeckt werden könnte.
- Jede Erweiterungsmethode kann problemlos in eine normale statische Methode umgeschrieben werden.
- Code kann mithilfe von Teilklassen in Dateien getrennt werden, auch wenn keine Erweiterungsmethoden vorhanden waren.
Andererseits können wir Ihre Behauptung aufgreifen, dass sie niemals extrem notwendig sind:
- Warum brauchen wir Klassenmethoden, wenn wir immer statische Methoden mit einem Namen erstellen können, der eindeutig angibt, dass es sich um eine bestimmte Klasse handelt?
Die Antwort auf diese und Ihre Frage bleibt dieselbe:
- Schönere Syntax
- Verbesserte Lesbarkeit und weniger Code-Pedanterie (Code wird in weniger Zeichen auf den Punkt gebracht)
- Intellisense liefert kontextbezogene Ergebnisse (Erweiterungsmethoden werden nur für den richtigen Typ angezeigt. Statische Klassen können überall verwendet werden).
Eine besondere Erwähnung:
- Erweiterungsmethoden ermöglichen eine Verkettung des Codierungsstils. Dies ist in letzter Zeit populärer geworden, im Gegensatz zu der Vanille-Methoden-Wrapping-Syntax. Ähnliche syntaktische Einstellungen finden Sie in der Methodensyntax von LINQ.
- Während die Methodenverkettung auch mithilfe von Klassenmethoden durchgeführt werden kann; Beachten Sie, dass dies für statische Methoden nicht ganz gilt. Erweiterungsmethoden basieren am häufigsten auf Dingen, die sonst statische Methoden gewesen wären, nicht auf Klassenmethoden.