Ich bin relativ neu in C # und jedes Mal, wenn ich anfange, an einem C # -Projekt zu arbeiten (ich habe nur an fast ausgereiften Projekten in C # gearbeitet), frage ich mich, warum es keine inneren Klassen gibt.
Vielleicht verstehe ich ihr Ziel nicht. Für mich sehen innere Klassen - zumindest private innere Klassen - sehr nach "inneren Prozeduren" in Pascal / Modula-2 / Ada aus: Sie ermöglichen es, eine Hauptklasse in kleinere Teile aufzuteilen, um das Verständnis zu erleichtern.
Beispiel: Hier ist, was die meiste Zeit zu sehen ist:
public class ClassA
{
public MethodA()
{
<some code>
myObjectClassB.DoSomething(); // ClassB is only used by ClassA
<some code>
}
}
public class ClassB
{
public DoSomething()
{
}
}
Da ClassB (zumindest für eine Weile) nur von ClassA verwendet wird, gehe ich davon aus, dass dieser Code besser wie folgt ausgedrückt werden sollte:
public class ClassA
{
public MethodA()
{
<some code>
myObjectClassB.DoSomething(); // Class B is only usable by ClassA
<some code>
}
private class ClassB
{
public DoSomething()
{
}
}
}
Ich würde mich freuen, von Ihnen zu diesem Thema zu hören - Habe ich recht?
quelle
Antworten:
Verschachtelte Klassen (wahrscheinlich am besten, um das Wort "inner" zu vermeiden, da verschachtelte Klassen in C # etwas anders sind als innere Klassen in Java) können in der Tat sehr nützlich sein.
Ein Muster, das nicht erwähnt wurde, ist das "bessere Aufzählungsmuster" - das noch flexibler sein kann als das in Java:
public abstract class MyCleverEnum { public static readonly MyCleverEnum First = new FirstCleverEnum(); public static readonly MyCleverEnum Second = new SecondCleverEnum(); // Can only be called by this type *and nested types* private MyCleverEnum() { } public abstract void SomeMethod(); public abstract void AnotherMethod(); private class FirstCleverEnum : MyCleverEnum { public override void SomeMethod() { // First-specific behaviour here } public override void AnotherMethod() { // First-specific behaviour here } } private class SecondCleverEnum : MyCleverEnum { public override void SomeMethod() { // Second-specific behaviour here } public override void AnotherMethod() { // Second-specific behaviour here } } }
Wir könnten eine gewisse Sprachunterstützung gebrauchen, um einige davon automatisch zu erledigen - und es gibt viele Optionen, die ich hier nicht gezeigt habe, z. B. nicht für alle Werte eine verschachtelte Klasse oder für mehrere Werte dieselbe verschachtelte Klasse zu verwenden. aber ihnen verschiedene Konstruktorparameter geben. Grundsätzlich bietet die Tatsache, dass die verschachtelte Klasse den privaten Konstruktor aufrufen kann, viel Leistung.
quelle
MyCleverEnum
fungiert sowohl als Inhaber der Enum-Mitglieder als auch als Schnittstelle jedes Enum-Mitglieds und ist daher prägnanter als andere Lösungen. Durch die Verwendung eingebetteter Klassen wird sichergestellt, dass die Unterstützungsklassen außerhalb der Klasse verborgen sind. Der private Konstruktor bewirkt, dass sich die Klasse von außerhalb der Klasse wie eine statische / Singleton-Klasse verhält, von innen jedoch wie eine abstrakte Basisklasse.using FirstCleverEnum = MyCleverEnum.FirstCleverEnum
. Dies kann das Problem mindern, aber es gibt keine Möglichkeit, diesen Alias zu "exportieren".Die Framework Design Guidelines enthalten die besten Regeln für die Verwendung verschachtelter Klassen, die ich bisher gefunden habe.
Hier ist eine kurze zusammenfassende Liste:
quelle
Sie sollten die Verantwortlichkeiten jeder Klasse einschränken, damit jede Klasse einfach, testbar und wiederverwendbar bleibt . Private innere Klassen gehen dagegen vor. Sie tragen zur Komplexität der äußeren Klasse bei, sind nicht testbar und nicht wiederverwendbar.
quelle
Für mich persönlich erstelle ich private innere Klassen nur, wenn ich in Bearbeitung befindliche Sammlungen eines Objekts erstellen muss, für die möglicherweise Methoden erforderlich sind.
Andernfalls kann es für andere Entwickler, die an dem Projekt arbeiten, zu Verwirrung kommen, diese Klassen tatsächlich zu finden, da sie nicht genau wissen, wo sie sich befinden.
quelle