c# - template - github ardalis clean architecture




Wann ist es angebracht, partielle C#-Klassen zu verwenden? (14)

  1. Mehrere Entwickler, die partielle Klassen verwenden, können mehrere Entwickler problemlos an derselben Klasse arbeiten.
  2. Codegenerator Teilklassen werden hauptsächlich vom Codegenerator verwendet, um unterschiedliche Probleme getrennt zu halten
  3. Teilmethoden Mit partiellen Klassen können Sie auch partielle Methoden definieren, bei denen ein Entwickler die Methode einfach definieren kann und der andere Entwickler diese implementieren kann.
  4. Partial Method Declaration only Auch der Code wird nur mit Methodendeklaration kompiliert und wenn die Implementierung der Methode nicht vorhanden ist, kann der Compiler das Codeelement sicher entfernen und es wird kein Kompilierzeitfehler auftreten.

    Um Punkt 4 zu verifizieren, erstellen Sie einfach ein Winform-Projekt und fügen Sie diese Zeile nach dem Form1-Konstruktor ein und versuchen Sie, den Code zu kompilieren

    partial void Ontest(string s);
    

Hier sind einige Punkte, die bei der Implementierung von Teilklassen zu beachten sind:

  1. Verwenden Sie partielles Schlüsselwort in jedem Teil der partiellen Klasse.
  2. Der Name jedes Teils der partiellen Klasse sollte gleich sein, aber der Name der Quelldatei für jeden Teil der partiellen Klasse kann unterschiedlich sein.
  3. Alle Teile einer partiellen Klasse sollten sich im selben Namespace befinden.
  4. Jeder Teil einer partiellen Klasse sollte sich in derselben Assembly oder DLL befinden. Mit anderen Worten, Sie können keine partielle Klasse in Quelldateien aus einem anderen Klassenbibliotheksprojekt erstellen.
  5. Jeder Teil einer Teilklasse muss dieselbe Erreichbarkeit haben. (dh: privat, öffentlich oder geschützt)
  6. Wenn Sie eine Klasse oder Schnittstelle für eine partielle Klasse erben, wird sie von allen Teilen dieser partiellen Klasse geerbt.
  7. Wenn ein Teil einer Teilklasse versiegelt ist, wird die gesamte Klasse versiegelt.
  8. Wenn ein Teil der partiellen Klasse abstrakt ist, wird die gesamte Klasse als abstrakte Klasse betrachtet.

Ich habe mich gefragt, ob mir jemand einen Überblick geben könnte, warum ich sie verwenden würde und welchen Vorteil ich dabei gewinnen würde.


Abgesehen von den anderen Antworten ...

Ich habe sie hilfreich als Sprungbrett bei der Umgestaltung von Gottheiten gefunden. Wenn eine Klasse mehrere Verantwortlichkeiten hat (besonders wenn es eine sehr große Code-Datei ist), dann finde ich es nützlich, 1x Partial Class Per-Responsibility als First-Pass zum Organisieren und Refactoring des Codes hinzuzufügen.

Dies hilft sehr, da es helfen kann, den Code viel lesbarer zu machen, ohne das ausführende Verhalten tatsächlich zu beeinflussen. Es kann auch helfen, zu erkennen, wann eine Verantwortung einfach umgestaltet werden kann oder eng mit anderen Aspekten verwoben ist.

Allerdings - um es klar zu sagen - das ist immer noch schlechter Code, am Ende der Entwicklung wollen Sie immer noch eine Verantwortung pro Klasse ( NICHT pro Teilklasse). Es ist nur ein Sprungbrett :)


Die Hauptverwendung für partielle Klassen ist mit generiertem Code. Wenn Sie sich das WPF-Netzwerk (Windows Presentation Foundation) ansehen, definieren Sie Ihre Benutzeroberfläche mit Markup (XML). Dieses Markup wird in partielle Klassen kompiliert. Sie geben Code mit eigenen Teilklassen ein.


Die größte Verwendung von Teilklassen besteht darin, Codegeneratoren / Designern das Leben zu erleichtern. Partielle Klassen erlauben dem Generator, den Code, den sie weglassen müssen, einfach wegzulassen, und sie müssen sich nicht mit Benutzerbearbeitungen der Datei befassen. Benutzer können ebenfalls die Klasse mit neuen Mitgliedern annotieren, indem sie eine zweite Teilklasse haben. Dies bietet einen sehr sauberen Rahmen für die Trennung von Bedenken.

Eine bessere Möglichkeit, es zu betrachten, ist zu sehen, wie Designer vor Teilklassen funktionierten. Der WinForms-Designer würde den gesamten Code innerhalb einer Region mit stark formulierten Kommentaren darüber ausspucken, den Code nicht zu ändern. Es musste alle Arten von Heuristiken einfügen, um den generierten Code für die spätere Verarbeitung zu finden. Jetzt kann es einfach die Datei designer.cs öffnen und ein hohes Maß an Vertrauen haben, dass es nur Code enthält, der für den Designer relevant ist.


Dienstverweise sind ein weiteres Beispiel, bei dem partielle Klassen nützlich sind, um generierten Code vom vom Benutzer erstellten Code zu trennen.

Sie können die Serviceklassen "erweitern", ohne sie beim Aktualisieren der Servicereferenz zu überschreiben.


Ein großer Vorteil ist die Trennung von generiertem Code von handgeschriebenem Code, der zur selben Klasse gehört.

Zum Beispiel, weil LINQ to SQL partielle Klassen verwendet, können Sie Ihre eigene Implementierung bestimmter Funktionen (wie Viele-zu-Viele-Beziehungen) schreiben und diese Teile von benutzerdefiniertem Code werden nicht überschrieben, wenn Sie den Code neu generieren.

Dasselbe gilt für den WinForms-Code. Der gesamte von Designer generierte Code wird in eine Datei geschrieben, die Sie im Allgemeinen nicht berühren. Ihr handschriftlicher Code wird in eine andere Datei geschrieben. Auf diese Weise werden Ihre Änderungen nicht verändert, wenn Sie etwas in Designer ändern.


Eine andere Verwendung, die ich sah, ist,

Erweitern einer großen abstrakten Klasse in Bezug auf Datenzugriffslogik,

Ich habe verschiedene Dateien mit den Namen Post.cs, Comment.cs, Pages.cs ...

in Post.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of post..
}


in Comment.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of comment..
}

in Pages.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of Pages..
}

Es ist richtig, dass Partial Class bei der automatischen Codegenerierung verwendet wird, eine Verwendung kann das Beibehalten einer großen Klassendatei sein, die tausend Zeilen Code haben kann. Sie wissen nie, dass Ihre Klasse mit 10 000 Zeilen endet und Sie möchten keine neue Klasse mit anderem Namen erstellen.

public partial class Product
{
    // 50 business logic embedded in methods and properties..
}

public partial class Product
{
    // another 50 business logic embedded in methods and properties..
}
//finally compile with product.class file.

Eine andere mögliche Verwendung könnte sein, dass mehr als ein Entwickler an derselben Klasse arbeiten kann, wie sie an verschiedenen Orten gespeichert sind. Die Leute lachen vielleicht, aber man weiß nie, dass es manchmal handvoll sein kann.

Produkt1.cs

public partial class Product
{
    //you are writing the business logic for fast moving product
}

Produkt2.cs

public partial class Product
{
    // Another developer writing some business logic...
}

Hoffe es ergibt Sinn!


Ich weiß, dass diese Frage wirklich alt ist, aber ich möchte nur meinen Teilunterricht hinzufügen.

Ein Grund, warum ich persönlich Teilklassen verwende, ist, wenn ich Bindungen für ein Programm erzeuge, insbesondere für Zustandsautomaten.

Zum Beispiel, OpenGL ist eine Zustandsmaschine, es gibt Haufen von Methoden, die alle global geändert werden können, jedoch in meiner Erfahrung binden etwas ähnlich OpenGL, wo es so viele Methoden gibt, kann die Klasse 10k LOC leicht überschreiten.

Teilklassen werden das für mich durchbrechen und mir helfen, schnell Methoden zu finden.


Immer wenn ich eine Klasse habe, die eine geschachtelte Klasse enthält, die eine signifikante Größe / Komplexität aufweist, markiere ich die Klasse als partial und lege die verschachtelte Klasse in eine separate Datei. Ich benenne die Datei, die die geschachtelte Klasse enthält, mit der Regel: [Klassenname]. [Name der geschachtelten Klasse] .cs.

Das folgende MSDN-Blog erläutert die Verwendung von partiellen Klassen mit geschachtelten Klassen für die Wartbarkeit: http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for-maintainability.aspx


Partielle Klassen werden hauptsächlich eingeführt, um Code-Generatoren zu helfen, so dass wir (unsere Benutzer) nicht jedes Mal unsere gesamte Arbeit / Änderungen an den generierten Klassen wie der ASP.NET-Klasse .designer.cs jedes Mal verlieren, wenn wir neu generieren, fast alle neuen Tools, die generieren Code LINQ, EntityFrameworks, ASP.NET verwenden partielle Klassen für generierten Code, sodass wir die Logik dieser generierten Codes unter Verwendung von Partial-Klassen und -Methoden sicher hinzufügen oder ändern können, aber seien Sie vorsichtig, bevor Sie dem generierten Code mithilfe von Partial-Klassen etwas hinzufügen es ist einfacher, wenn wir den Build unterbrechen, aber am schlimmsten, wenn wir Laufzeitfehler einführen. Für weitere Details überprüfen Sie diese http://www.4guysfromrolla.com/articles/071509-1.aspx


Teilklassen machen es möglich, Funktionalität zu einem geeignet entworfenen Programm hinzuzufügen, indem lediglich Quelldateien hinzugefügt werden. Zum Beispiel könnte ein Programm zum Importieren von Dateien so entworfen werden, dass man verschiedene Arten von bekannten Dateien hinzufügen könnte, indem man Module hinzufügt, die sie handhaben. Der Hauptdateitypkonverter könnte beispielsweise eine kleine Klasse enthalten:

Partial Public Class zzFileConverterRegistrar
    Event Register(ByVal mainConverter as zzFileConverter)
    Sub registerAll(ByVal mainConverter as zzFileConverter)
        RaiseEvent Register(mainConverter)
    End Sub
End Class

Jedes Modul, das einen oder mehrere Arten von Dateikonvertern registrieren möchte, könnte Folgendes enthalten:

Partial Public Class zzFileConverterRegistrar
    Private Sub RegisterGif(ByVal mainConverter as zzFileConverter) Handles Me.Register
        mainConverter.RegisterConverter("GIF", GifConverter.NewFactory))
    End Sub
End Class

Beachten Sie, dass die Hauptdateikonverterklasse nicht "exposed" ist - sie stellt nur eine kleine Stub-Klasse dar, zu der Add-In-Module haken können. Es besteht ein geringes Risiko von Namenskonflikten, aber wenn die "Register" -Routine jedes Add-In-Moduls entsprechend dem Dateityp benannt wird, den es behandelt, sollten sie wahrscheinlich kein Problem darstellen. Man könnte eine GUID im Namen der Registrierungsunterroutine stecken, wenn man sich über solche Dinge Sorgen macht.

Edit / Addendum Um dies klarzustellen, besteht der Zweck darin, ein Mittel zur Verfügung zu stellen, mit dem eine Vielzahl von separaten Klassen ein Hauptprogramm oder eine Klasse über sie informieren kann. Das einzige, was der Hauptdateikonverter mit zzFileConverterRegistrar tun wird, ist eine Instanz davon zu erstellen und die registerAll-Methode aufzurufen, die das Register-Ereignis auslöst. Jedes Modul, das dieses Ereignis haken möchte, kann beliebigen Code als Antwort darauf ausführen (das ist die ganze Idee), aber es gibt nichts, was ein Modul tun könnte, indem es die zzFileConverterRegistrar-Klasse anders als eine Methode definiert, deren Name mit etwas anderem übereinstimmt . Es wäre sicherlich möglich, dass eine falsch geschriebene Erweiterung eine andere falsch geschriebene Erweiterung unterbricht, aber die Lösung dafür ist für jeden, der nicht möchte, dass seine Erweiterung nicht richtig geschrieben wird.

Man könnte, ohne partielle Klassen zu verwenden, irgendwo in der Hauptdateikonverterklasse ein wenig Code haben, der wie folgt aussieht:

  RegisterConverter("GIF", GifConvertor.NewFactory)
  RegisterConverter("BMP", BmpConvertor.NewFactory)
  RegisterConverter("JPEG", JpegConvertor.NewFactory)

aber das Hinzufügen eines anderen Konvertermoduls würde es erforderlich machen, in diesen Teil des Konvertercodes zu gehen und den neuen Konverter zu der Liste hinzuzufügen. Mit partiellen Methoden ist das nicht mehr nötig - alle Konverter werden automatisch eingebunden.


Wenn Sie eine ausreichend große Klasse haben, die sich nicht für eine effektive Umgestaltung eignet, hilft die Trennung in mehrere Dateien, die Dinge zu organisieren.

Wenn Sie zum Beispiel eine Datenbank für eine Site haben, die ein Diskussionsforum und ein Produktsystem enthält, und Sie nicht zwei verschiedene Provider-Klassen erstellen möchten (NICHT das gleiche wie eine Proxy-Klasse, nur um klar zu sein), können Sie das tun Erstelle eine einzelne Teilklasse in verschiedenen Dateien, wie

MyProvider.cs - Kernlogik

MyProvider.Forum.cs - Methoden speziell für das Forum

MyProvider.Product.cs - Methoden für Produkte

Es ist nur ein weiterer Weg, um die Dinge organisiert zu halten.

Wie andere bereits gesagt haben, ist dies der einzige Weg, Methoden zu einer generierten Klasse hinzuzufügen, ohne das Risiko einzugehen, dass Ihre Additionen beim nächsten Generieren der Klasse zerstört werden. Dies ist nützlich bei Templates (T4), ORMs usw.


halte alles so sauber wie möglich, wenn du mit riesigen Klassen arbeitest, oder wenn du in einem Team arbeitest, kannst du es bearbeiten, ohne es zu überschreiben (oder immer Änderungen vorzunehmen)





architecture