Nach meinem Verständnis partial
bewirkt das Schlüsselwort nichts anderes, als die Aufteilung einer Klasse auf mehrere Quelldateien. Gibt es einen Grund, dies anders als für die Code-Organisation zu tun? Ich habe gesehen, dass es dafür in generierten UI-Klassen verwendet wird.
Es scheint ein schlechter Grund zu sein, ein ganzes Keyword zu erstellen. Wenn eine Klasse groß genug ist, um mehrere Dateien zu benötigen, tut sie wahrscheinlich zu viel. Ich dachte, dass Sie es vielleicht verwenden könnten, um eine Klasse für einen anderen Programmierer teilweise zu definieren, aber es wäre besser, eine abstrakte Klasse zu erstellen.
c#
design
language-design
Michael K
quelle
quelle
partial
Bedeutet nur etwas, wenn es vorher kommtclass
. Sie können es als Bezeichnername in anderen Teilen des Codes usw. verwenden.Antworten:
Dies ist in jedem Szenario sehr nützlich, in dem ein Teil der Klasse von einem benutzerdefinierten Tool generiert wird, da Sie dem generierten Code benutzerdefinierte Logik hinzufügen können, ohne die generierte Klasse zu erben. Btw. Aus dem gleichen Grund gibt es auch Teilmethoden.
Es geht nicht nur um die Benutzeroberfläche, sondern auch um andere Technologien wie Linq-To-Sql oder Entity Framework.
quelle
Wie Sie sagen, wird es oft verwendet, um generierten Code zu trennen. Es hat oft nichts mit der Größe von Klassen / Dateien zu tun.
Der Vorteil des Trennens des generierten Codes liegt im Stil. Generierter Code kann ziemlich hässlich und unlesbar sein und würde viele Codierungsstandards (und StyleCop-Prüfungen) nicht erfüllen, aber das ist in Ordnung, niemand muss ihn lesen oder direkt warten. Wenn Sie es also in einer anderen Datei "verstecken", können Sie sich darauf konzentrieren, sicherzustellen, dass der Rest der Klasse dem Standard entspricht, die StyleCop-Prüfungen bestehen und so weiter.
Ein anderer Bereich, in dem ich es verwendet habe, ist der, in dem eine Klasse mehrere Schnittstellen implementiert. Es kann ganz nett sein, die Implementierung in separate Dateien zu unterteilen. Dies ist jedoch eher eine Frage der persönlichen Präferenz. Ich habe noch nie gesehen, dass Kodierungsstandards dies erfordern ( oder verhindern) dies.
quelle
Einer der Entwickler, bei dem ich arbeite, hat sich vor ein paar Wochen eine ziemlich gute Verwendung für sie ausgedacht, um riesige Gottklassen umzugestalten, die außer Kontrolle geraten sind und viele öffentliche Methoden haben: indem sie die logischen Funktionen der einzelnen Teile voneinander trennen Die Klasse in separate Teilklassen Sie können die Klasse physisch in die atomaren Einheiten unterteilen, die die Klassen sein sollen, ohne vorhandene Funktionen zu unterbrechen. So können Sie sehen, was gemeinsam ist und was nicht. In dieser ersten Phase können Sie die Partials dann einfacher in ihre eigenen unabhängigen Klassen aufteilen und in der gesamten Codebasis implementieren. Ich fand das eine schöne Idee.
Im Allgemeinen denke ich jedoch, dass sie nur verwendet werden sollten, um maschinengenerierte Klassen beim Schreiben von neuem Code zu erweitern.
quelle
Ich kann mir einige nützliche Szenarien vorstellen, in denen Teilweise sinnvoll sind. Die meisten davon benutze ich selbst in meinen Projekten:
So trennen Sie den von Tool / IDE / Designer generierten Code von dem von Ihnen verwalteten Code. Ein gutes Beispiel ist die
Form.Designer.cs
Datei, die den vom Designer generierten Code für Windows Forms-Anwendungen enthält. Viele andere .NET-Formate verfügen auch über einen vom Tool generierten Code, der möglicherweise beim Erstellen Ihres Projekts neu generiert werden kann, sodass alle Ihre benutzerdefinierten Änderungen verworfen werden. Die Trennung hilft Ihnen dabei, Ihren Code und Änderungen vor solchen automatisierten Änderungen zu schützen.Wenn Sie mehrere Schnittstellen mit viel Code in der Implementierung implementieren. Ich neige dazu , eine separate Teildatei für jede solche Schnittstelle zu verwenden, es so zu benennen:
{Class}.{Interface}.cs
. In der IDE ist leicht zu erkennen, welche Schnittstellen die{Class}
implementieren und wie.Wenn die Klasse eine oder mehrere verschachtelte Klassen enthalten muss , insbesondere mit genügend Code, um in einer separaten Datei abgelegt zu werden. Ich würde mich an das obige Muster halten und die
{Class}.{NestedClass}.cs
Namenskonvention für jede verschachtelte Klasse verwenden. Eine ähnliche Praxis wird bereits in der Antwort von Virtlink erwähnt .Wenn ich
static
Klassen schreibe , die Erweiterungsmethoden enthalten . Es ist häufig der Fall, ähnliche Klassen oder Schnittstellen mit der gleichen Erweiterungsmethodenlogik auszustatten - wie zum BeispielReverse
bei generischen und nicht generischen Auflistungen. Ich würde alle Erweiterungsmethoden für eine einzelne Klasse oder Schnittstelle in einen separaten Teil der statischen Klasse setzen. Zum Beispiel hätte ich alle Erweiterungsmethoden für dieIList
Schnittstelle an einem Ort und die gleichen Methoden, die fürIList<T>
in einer anderen Datei sind. Ein anderer Ansatz wäre, die gleiche Methode (alle Überladungen) mit allen möglichen Klassen für denthis
Parameter in den gleichen Teil zu setzen - wie mit allenReverse
Implementierungen in einer Datei. Es hängt davon ab, an welcher Stelle die Trennung in Bezug auf das Codevolumen oder auf einige interne Konventionen, die Sie oder Ihre Organisation möglicherweise einhalten, besser gerechtfertigt ist.Ich verwende dies nicht, aber ich habe gesehen, dass einige C / C ++ - Leute den Ansatz mögen, den ich hier beschreiben werde: erstelle einen Teil für die Klasse mit nur teilweisen Methoden . Dies ähnelt der C / C ++ - Methode zum Definieren von Schnittstellen und zum Trennen der Methodendeklaration von der Implementierung.
Trennung durch rein logische Bedenken . Wenn Sie zufällig mit einer großen Klasse arbeiten, die mehr als eine logische Gruppe von Operationen in sich vereint, können Sie jeden logisch verwandten Code in einen separaten Teil trennen. Gewöhnlich ist das Vorhandensein solcher Klassen gegen das Prinzip der Trennung von Interessen, aber es wird häufig im wirklichen Leben beobachtet, insbesondere bei älteren Codebasen. Mitbenutzer Steve Evers hat sie in seiner Antwort auf diese Frage erwähnt und sie mit dem Namen god objects bezeichnet. Ich persönlich würde den Ansatz von Teilklassen verwenden, um den Code zu teilen, bevor ein Refactoring von wirklich großen Dateien stattfindet, um meine Arbeit zu vereinfachen und das Refactoring transparenter zu machen. Dies wird auch die Konflikte verringern, die ich möglicherweise verursachen werde, wenn Versionsverwaltungssysteme wie SVN beteiligt sind.
quelle
Ich habe es von niemandem erwähnt gesehen: Ich
partial
setze verschachtelte Klassen in ihre eigenen Dateien.Alle meine Codedateien enthalten nur eine Klasse, Struktur, Schnittstelle oder Aufzählung. Es erleichtert das Auffinden der Definition für ein Objekt erheblich, wenn die Dateinamen den Namen des gesuchten Objekts anzeigen. Und da Visual Studio versucht, die Projektordner mit den Namespaces abzugleichen, sollten die Dateinamen mit den Klassen übereinstimmen.
Das bedeutet auch , dass eine Klasse
NestedClass
innerhalb verschachteltMyClass
wird seine eigene Datei in meinen Projekten haben:MyClass.NestedClass.cs
.quelle
Mit Ausnahme des generierten Codes verwenden, habe ich nur immer sie in dem Bemühen verwendet , gesehen zu verschleiern Gott Objekte . Der Versuch, eine neue Codebasis zu verstehen oder durch mehrere Quelldateien zu navigieren, bei denen es sich um dasselbe Objekt handelt, ist soooo ärgerlich.
Wenn Sie also fragen,
Why use partial classes?
antworte ich: Wenn Sie keinen generierten Code verwenden, tun Sie das nicht.quelle
Code-Organisation ist der einzige Grund, aber es geht tiefer, als es auf den ersten Blick scheint. Wenn Sie Teilklassen haben, in denen Teile generiert werden, können Sie einfach:
quelle
Es gibt auch einige Stellen, an denen generierte / implizierte Klassen als Teilklassen deklariert werden. Wenn der Entwickler sie erweitern muss, haben sie vollen Zugriff, ohne die Vererbung und das Überschreiben der gesamten Klasse zu beeinträchtigen. Schauen Sie sich die generierten Klassen im temporären Bereich von asp.net an, nachdem Sie zum ersten Mal eine Webforms-Site unter IIS ausgeführt haben, um einige Beispiele zu finden.
quelle
Ich kann mir eine schmutzige Verwendung für sie vorstellen.
Angenommen, Sie haben einige Klassen, die eine gemeinsame Funktionalität benötigen, diese Funktionalität jedoch nicht in die darüber liegende Vererbungskette einfügen möchten. Oder Sie haben eine Reihe von Klassen, die eine gemeinsame Hilfsklasse verwenden.
Grundsätzlich möchten Sie eine Mehrfachvererbung durchführen, aber C # mag dies nicht. Sie verwenden also partial, um das zu erstellen, was in C / C ++ im Wesentlichen ein # include ist.
Ordnen Sie alle Funktionen einer Klasse zu oder verwenden Sie die Hilfsklasse. Kopieren Sie dann den Helfer X-mal und benennen Sie ihn in Teilklasse A, B, C um. und teilweise auf Ihre Klassen A, B, C setzen.
Haftungsausschluss: Ja, das ist böse. Tu es niemals - besonders wenn es andere Leute wütend auf dich macht.
quelle