class - Wann ist es angebracht, partielle C#-Klassen zu verwenden?




architecture (18)

  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.


Hier ist eine Liste einiger Vorteile von Teilklassen.

Sie können den UI-Design-Code und den Business-Logik-Code so trennen, dass er leicht zu lesen und zu verstehen ist. Beispielsweise entwickeln Sie eine Webanwendung, die Visual Studio verwendet, und fügen ein neues Webformular hinzu, dann gibt es zwei Quelldateien "aspx.cs" und "aspx.designer.cs". Diese zwei Dateien haben dieselbe Klasse mit dem partiellen Schlüsselwort. Die Klasse ".aspx.cs" enthält den Geschäftslogikcode, während "aspx.designer.cs" die Steuerdefinition für die Benutzeroberfläche hat.

Wenn Sie mit einer automatisch generierten Quelle arbeiten, kann der Code zur Klasse hinzugefügt werden, ohne die Quelldatei neu erstellen zu müssen. Beispielsweise arbeiten Sie mit LINQ to SQL und erstellen eine DBML-Datei. Wenn Sie jetzt eine Tabelle ziehen und ablegen, erstellt sie eine partielle Klasse in designer.cs und alle Tabellenspalten haben Eigenschaften in der Klasse. Sie benötigen mehr Spalten in dieser Tabelle, um an das UI-Raster zu binden, aber Sie möchten der Datenbanktabelle keine neue Spalte hinzufügen, damit Sie eine separate Quelldatei für diese Klasse erstellen können, die eine neue Eigenschaft für diese Spalte hat sei eine Teilklasse. Das hat Auswirkungen auf die Zuordnung zwischen Datenbanktabelle und DBML-Entität, aber Sie können leicht ein zusätzliches Feld erhalten. Das bedeutet, dass Sie den Code selbst schreiben können, ohne den systemgenerierten Code zu stören.

Mehrere Entwickler können gleichzeitig den Code für die Klasse schreiben.

Sie können Ihre Anwendung besser verwalten, indem Sie große Klassen komprimieren. Angenommen, Sie verfügen über eine Klasse mit mehreren Schnittstellen, sodass Sie abhängig von den Schnittstellenwerkzeugen mehrere Quelldateien erstellen können. Es ist leicht zu verstehen und aufrechtzuerhalten eine Schnittstelle implementiert, auf der die Quelldatei eine partielle Klasse hat.


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.


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


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..
}

Partielle Klassen halfen kürzlich bei der Quellcodeverwaltung, wo mehrere Entwickler zu einer Datei hinzufügten, wo neue Methoden in denselben Teil der Datei hinzugefügt wurden (automatisiert von Resharper).

Diese Push-to-git-Konflikte verursachten Konflikte. Ich habe keine Möglichkeit gefunden, dem Merge-Tool mitzuteilen, dass die neuen Methoden als vollständiger Codeblock verwendet werden sollen.

Partielle Klassen in dieser Hinsicht erlauben Entwicklern, sich an eine Version ihrer Datei zu halten, und wir können sie später von Hand zusammenführen.

Beispiel -

  • MainClass.cs - enthält Felder, Konstruktor usw
  • MainClass1.cs - ein Entwickler neuer Code, wie sie implementieren
  • MainClass2.cs - ist eine weitere Entwicklerklasse für ihren neuen Code.

Von MSDN :

1.Zum Kompilierzeitpunkt werden Attribute von Partialtypdefinitionen zusammengeführt. Betrachten Sie beispielsweise die folgenden Deklarationen:

[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

Sie entsprechen den folgenden Deklarationen:

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }

Die folgenden Elemente werden aus allen Teildefinitionen zusammengeführt:

  • XML-Kommentare

  • Schnittstellen

  • generische Parameterattribute

  • Klassenattribute

  • Mitglieder

2. Eine andere Sache, verschachtelte Teilklassen können auch teilweise sein:

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

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!


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.


Als eine Alternative zu Pre-Compiler-Direktiven.

Wenn Sie Pre-Compiler-Direktiven (nämlich #IF DEBUG ) verwenden, dann haben Sie am Ende etwas gnarly Code mit Ihrem tatsächlichen Release-Code vermischt.

Sie können eine separate partielle Klasse erstellen, die diesen Code enthält, und entweder die gesamte partielle Klasse in eine Direktive einbinden oder diese Code-Datei davon abhalten, an den Compiler gesendet zu werden (was im Prinzip auch der Fall ist).


Die meisten Leute bemerken, dass partial nur für eine Klasse mit einer generierten Codedatei oder für Schnittstellen verwendet werden sollte. Ich stimme nicht zu, und hier ist warum.

Betrachten wir zum Beispiel die C # System.Math-Klasse ... das ist die Klasse . Ich würde nicht versuchen, mehr als 70 Methoden in dieselbe einzelne Codedatei zu stopfen. Es wäre ein Albtraum, es zu erhalten.

Wenn Sie jede mathematische Methode in einzelne partielle Klassendateien und alle Codedateien in einen Math-Ordner im Projekt einfügen, wäre die Organisation wesentlich sauberer.

Das gleiche könnte / würde für viele andere Klassen gelten, die eine große Menge an unterschiedlichen Funktionen haben. Zum Beispiel könnte eine Klasse zur Verwaltung der PrivateProfile-API von Vorteil sein, indem sie in einen sauberen Satz partieller Klassendateien in einem einzelnen Projektordner aufgeteilt wird.

Persönlich teile ich auch, was die meisten Leute "Helfer" oder "Dienstprogramm" -Klassen nennen, in einzelne Teildateien für jede Methode oder Methodenfunktionsgruppe. Zum Beispiel hat die String-Helper-Klasse in einem Projekt fast 50 Methoden. Das wäre eine lange sperrige Code-Datei, die sogar Regionen verwendet. Es ist wesentlich einfacher, einzelne partielle Klassendateien für jede Methode zu verwalten.

Ich würde nur vorsichtig sein, Teilklassen zu verwenden und das gesamte Layout der Codedatei während des gesamten Projekts konsistent zu halten. B. das Platzieren von öffentlichen Enums einer Klasse und privaten Membern einer Klasse in eine Common.cs-Datei oder eine ähnlich benannte Datei im Ordner, anstatt sie über die Dateien zu verteilen, sofern sie nicht nur für die Teildatei, in der sie enthalten sind, spezifisch sind.

Beachten Sie, dass Sie beim Teilen einer Klasse in separate Dateien auch die Möglichkeit verlieren, die Text-Editor-Trennleiste zu verwenden, mit der Sie zwei verschiedene Abschnitte einer aktuellen Datei gleichzeitig anzeigen können.


Teilklassen umfassen mehrere Dateien.

How can you use the partial modifier on a C# class declaration?

Mit partiell können Sie eine Klasse physisch in mehrere Dateien trennen.

Dies wird oft durch Code-Generatoren gemacht.

Beispiel

Mit normalen C # -Klassen können Sie keine Klasse in zwei separaten Dateien im selben Projekt deklarieren.

Aber mit dem partiellen Modifikator können Sie.

Dies ist nützlich, wenn eine Datei häufig bearbeitet wird und die andere maschinell oder selten bearbeitet wird.

An Example will clear your concept.

class Program
{
    static void Main()
    {
    A.A1();
    A.A2();
    }
}

//Contents of file A1.cs: C#

using System;

partial class A
{
    public static void A1()
    {
    Console.WriteLine("A1");
    }
}

//Contents of file A2.cs: C#

using System;

partial class A
{
    public static void A2()
    {
    Console.WriteLine("A2");
    }
}

Output

A1
A2

Teilweise ist hier erforderlich.

If you remove the partial modifier, you will get an error containing this text: [The namespace '<global namespace>' already contains a definition for 'A'].

Tipp: Um dies zu beheben, können Sie entweder das Schlüsselwort partially verwenden oder einen der Klassennamen ändern.

How does the C# compiler deal with partial classes?

Wenn Sie das obige Programm zerlegen, werden Sie sehen, dass die Dateien A1.cs und A2.cs beseitigt sind.

Sie werden feststellen, dass die Klasse A vorhanden ist.

IL Disassembler So: Klasse A enthält die Methoden A1 und A2 im selben Codebaustein. Die zwei Klassen wurden zu einem zusammengefasst.

Kompiliertes Ergebnis von A1.cs und A2.cs: C #

internal class A
{
    // Methods
    public static void A1()
    {
    Console.WriteLine("A1");
    }

    public static void A2()
    {
    Console.WriteLine("A2");
    }
}

Zusammenfassung

Teilklassen können bestimmte C # -Programmiersituationen vereinfachen.

Sie werden häufig in Visual Studio beim Erstellen von Windows Forms / WPF-Programmen verwendet.

Der maschinengenerierte C # -Code ist separat.

Oder Sie können die gesamte Beschreibung here .


Eine andere Verwendung ist die Aufteilung der Implementierung verschiedener Schnittstellen, zB:

partial class MyClass : IF1, IF2, IF3
{
    // main implementation of MyClass
}


partial class MyClass
{
    // implementation of IF1
}

partial class MyClass
{
    // implementation of IF2
}

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)


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.


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.


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 :)


Nachfolgend finden Sie eine nette Utility-Klasse für Enums

public static class EnumHelper
{
    public static int[] ToIntArray<T>(T[] value)
    {
        int[] result = new int[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = Convert.ToInt32(value[i]);
        return result;
    }

    public static T[] FromIntArray<T>(int[] value) 
    {
        T[] result = new T[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = (T)Enum.ToObject(typeof(T),value[i]);
        return result;
    }


    internal static T Parse<T>(string value, T defaultValue)
    {
        if (Enum.IsDefined(typeof(T), value))
            return (T) Enum.Parse(typeof (T), value);

        int num;
        if(int.TryParse(value,out num))
        {
            if (Enum.IsDefined(typeof(T), num))
                return (T)Enum.ToObject(typeof(T), num);
        }

        return defaultValue;
    }
}






c# class architecture