Sollte ich Erweiterungsmethoden einer Schnittstelle in die Datei interface.cs einfügen?

8

Stellen Sie sich diesen Aufbau vor:

public interface IMass{
    double Mass {get;}
}

public static class IMassExtension {
    public static double ToKg(this IMass massObject) {
        return massObject.Mass / 1000.0;
    }

    public static double CalculateInteractiveGravity(this IMass massObject, IMass otherMassObject)          
    {
         return blah;
    }
}

Ist es in Ordnung, die Erweiterungsklasse in dieselbe Datei wie die Schnittstelle (dh IMass.cs) zu stellen, oder sollte sie sich in einer separaten Datei (IMassExtension.cs) befinden?


Eine Basisklasse ist hier nicht möglich. Vorstellen

public class Person : Animal, IMass {}

und

public class House : Building, IMass {}
Moop
quelle
@ Yusubov Basisklasse wird hier nicht funktionieren, aktualisierte Frage
Moop

Antworten:

13

Ja, das ist völlig in Ordnung. Darüber hinaus möchte ich Sie dazu ermutigen, da dadurch die in der Benutzeroberfläche verfügbaren Funktionen besser erkennbar werden und gleichzeitig das Rauschen in "Welche Funktionen befinden sich in diesem Programm?" Reduziert wird. Ansicht im visuellen Studio.

Die einzigen Argumente, die ich dagegen gehört habe, sind:

  • "aber dann hast du 2 Typen pro Datei!" - Richtlinien sollen Ihnen helfen, nicht Ihre Hände binden. Sie würden es nur einen Typ machen, wenn Sie könnten.
  • "Aber diese Erweiterung verwendet XYZ!" - Ja, wenn Sie die Methode nicht einschließen würden, wenn es sich um eine abstrakte Klasse handeln würde, sollten Sie sie auch nicht fest mit der Schnittstelle verbinden. Das ist kein Problem mit dieser Praxis, sondern mit Ihrem Design.
Telastyn
quelle
Neue
Sprachfunktionen
2

Zusammenfassend: Die Erweiterungsmethoden in einer separaten Datei zu haben, wäre der richtige Ansatz. Es ist auch sehr wichtig, Erweiterungen entsprechend zu benennen, da dies definitiv die Zeit während der Wartung spart.

Ich würde es vorziehen , auf jeden Fall den Namen MassExtensionsüber IMassExtensions. Der Grund dafür ist, dass für die meisten Programmierer ein I-Präfix für einen Typ impliziert, dass es sich um eine Schnittstelle handelt. Dies ist sowohl ein sehr verbreitetes Muster als auch Teil der .NET-Entwurfsrichtlinien.

Das Hinzufügen eines I-Präfixes für den Fall der Erweiterungsmethode verstößt sowohl gegen Annahmen als auch gegen festgelegte Richtlinien.

Dies hat auch in der Basisklassenbibliothek Vorrang. Die meisten verfügbaren Erweiterungsmethoden IEnumerablesind im Typ enthalten Enumerable.

Folgende verwandte Beiträge könnten hilfreich sein:

Yusubov
quelle
Dieser Blog-Beitrag empfiehlt gegen denselben Namespace: blogs.msdn.com/b/vbteam/archive/2007/03/10/…
Moop
Stimmen Sie zu, es sollte in ihren eigenen Namespaces sein
Yusubov
1

Normalerweise würde ich Erweiterungsmethoden nicht in dieselbe Datei wie die Schnittstelle einfügen. Gleiche Bibliothek / Paket? Sicher.

In diesem Beispiel würde ich definitiv nicht. Was wäre, wenn jemand Masse in imperialen Einheiten (Schnecken) implementieren würde? Das toKg () sollte sich in der Schnittstelle befinden (und möglicherweise auch toSlug (), aber das wäre technisch von toKg () ableitbar), und die Erweiterungsmethoden wären Methoden wie toG (), toMcg () usw., die könnte unter Verwendung der Schnittstellenmethoden implementiert werden.

Kristian H.
quelle
0

Ich würde es in eine separate Datei einfügen und ihm einen aussagekräftigeren Namen als "IMassExtension.cs" geben. Vielleicht so etwas wie "MassConversions.cs", da die Klasse das tatsächlich tut.

Vergessen Sie nicht, dass die Erweiterungsmethoden immer noch so aufgerufen werden können, als wären sie einfache statische Methoden (z. B. MassConversions.ToKg(massObject)). Daher sollte die Klasse unter diesem Gesichtspunkt benannt werden. Außerdem ist Ihre Erweiterungsklasse keine Schnittstelle, daher kann es irreführend sein, sie mit dem führenden "I" zu benennen.

Eric King
quelle
Nun, dies ist nur ein einfaches Beispiel, ich habe eine Reihe von Erweiterungsmethoden, die verschiedene Dinge tun, und es gibt keinen guten gemeinsamen Namen dafür
Moop
Dies könnte ein Zeichen dafür sein, dass weitere Überlegungen zur Organisation der Funktionalität angestellt werden sollten. "Küchenspülen" -Klassen sind häufig Quellen für viel Qual und sollten im Allgemeinen vermieden werden. Nur weil die Funktionalität in Form von Erweiterungsmethoden angezeigt wird, ist dies kein Grund, auf eine gute Klassenstruktur zu verzichten.
Eric King
Ich habe die Frage aktualisiert, um einen möglichen Grund aufzuzeigen, warum sie für dieses Design nützlich ist.
Moop
Ich sehe Ihr Update und mein Kommentar gilt weiterhin. Erstellen Sie separate (entsprechend benannte) Klassen für separate Funktionalitätstypen. Meiner Meinung nach ist es praktisch, aber schlampig, alle in dieselbe Klasse zu werfen.
Eric King
Sagst du das Animial : Massund Building : Masswenn Masswar eine Basisklasse?
Moop