Sollten Sie jemals private Felder und Methoden in C # verwenden?

8

Ich bin etwas neu in C # und habe gerade herausgefunden, dass: In C # sind alle Felder und Methoden in einer Klasse standardmäßig privat. Das bedeutet, dass dies:

class MyClass
{

string myString

}

ist das gleiche wie:

class MyClass
{

private string myString

}

Sollte ich das Schlüsselwort private für Felder und Methoden verwenden, weil sie gleich sind? Viele Online-Codebeispiele verwenden das Schlüsselwort private in ihrem Code. Warum ist das so?

user3210251
quelle
34
Zunächst einmal wird deutlich, dass Sie Ihr Feld privat machen wollten, anstatt nur zu vergessen, einen Bereichsspezifizierer einzuschließen.
KChaloux
4
Es ist mir unangenehm, nicht zu benutzen private. Es führt zu weniger kognitiven Dissonanzen für mich, wenn ich immer erwarten kann, dass der Bereichsspezifizierer als erster Teil einer Bezeichnerdeklaration angezeigt wird. Ich brauche weniger Zeit, um "privat" zu lesen, als um herauszufinden, dass das erste Wort kein Bereichsspezifizierer ist, und das bedeutet, dass es sich um eine private Mitgliedererklärung handelt. Beim Schreiben von Code muss es auch später gelesen werden.
Robert Harvey
3
@ RobertHarvey Es kann auch völlig subjektiv sein; Beim Codieren in C ++ habe ich immer alles weggelassen, was optional war, weil ich mich dadurch abgelenkt fühlte, bis mir klar wurde, dass andere Leute, die meinen Code lesen, möglicherweise an ausführlichere Codierungskonventionen gewöhnt sind. Es ist also eine Frage des Geschmacks (bei einem persönlichen Projekt) und der Konvention (bei der Zusammenarbeit).
Marczellm
2
@gnat Ich bin nicht sicher, ob dies ein Duplikat dieser Frage ist. Bist du sicher, dass du den richtigen Link gepostet hast?
maple_shaft
4
@gnat Es ist eine Strecke zu fragen, warum man das private Schlüsselwort in ihrem Code explizit deklarieren würde, ist eine Frage zum Codierungsstil. Diese Frage ist weitaus spezifischer. Ich bin der Meinung, dass eine kanonische Antwort zwar eine andere Frage abdeckt, eine spezifischere Frage jedoch manchmal eine eigene Antwort verdient.
maple_shaft

Antworten:

38

Nur weil Sie Zeilenvorschübe und Einrückungen weglassen können und Ihr C # -Compiler immer noch versteht, was Sie ihm sagen möchten, ist dies nicht automatisch eine gute Idee.

using System; namespace HelloWorld{class 
Hello{static void Main(){Console.WriteLine
("Hello World!");}}}

ist für den menschlichen Leser viel weniger lesbar als:

using System;
namespace HelloWorld
{
    class Hello 
    {
        static void Main() 
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Und das ist der springende Punkt hier - Programme sind für zwei Zielgruppen geschrieben:

  • Der Compiler oder Interpreter.
  • Sie selbst und andere Programmierer.

Letzterer ist derjenige, der die Bedeutung des Geschriebenen verstehen und schnell erfassen muss . Aus diesem Grund haben sich im Laufe der Jahre einige bewährte Verfahren herausgebildet, die mehr oder weniger allgemein als Quasi-Standards anerkannt sind. Eines davon ist das Setzen expliziter Bereichsschlüsselwörter, ein anderes Beispiel das Setzen zusätzlicher Klammern um komplexe Ausdrücke, selbst in Fällen, in denen sie syntaktisch nicht benötigt würden, wie z.

(2 + 5) & 4
JensG
quelle
2
+1 Insbesondere für diesen letzten Punkt. Während Programmierer genau genommen die Reihenfolge der Operationen für ihre Sprache kennen sollten, versuche ich immer, wenn möglich zusätzliche Klammern hinzuzufügen, da ich in der Vergangenheit einige Sekunden damit verbracht habe, zu überlegen, welche Operation zuerst kommt und ob ein Ausdruck die auswertet oder nicht so wie ich es denke. Gelegentlich wird die Antwort „Nein, ich habe es falsch“ und diese Gelegenheiten können mit sinnvollen Einsatz von Klammern vermieden werden, vor allem wenn man Fälle betrachten, wie 5 + 5 * 5ist 30, nicht 50wie einige vielleicht auf den ersten Blick erwarten.
Pharap
1
+1. Es gibt ein leichtes geistiges Schluckauf für mich, wenn ich keine expliziten Sichtbarkeitsmodifikatoren sehe. Ich muss für den Bruchteil einer Sekunde nachdenken: "Ist die Standardeinstellung öffentlich oder privat?" einfach, weil ich immer die Modifikatoren benutze und wenn jemand es nicht tut, wirft es mich ab.
Greg Bair
6
Du meinst **private** static void Main()? :)
Jesse C. Slicer
6

C # ist nicht die einzige Programmiersprache für .NET. Andere Sprachen können und haben in verschiedenen Kontexten unterschiedliche Standardzugriffsmöglichkeiten. Durch die Angabe privatewird jedem, der den Code liest , klar, dass eine solche Zugänglichkeit beabsichtigt ist, während durch das Weglassen der Angabe die Frage offen bleibt, ob das Mitglied möglicherweise innerhalb der Assembly verwendet werden soll [wie dies in VB.NET die Standardeinstellung wäre]. . Explizit zu sein kann besonders nützlich sein, wenn mehrere Sprachen mit unterschiedlichen Regeln verwendet werden.

In Bezug darauf, ob in Ermangelung eines besonders zwingenden Arguments zugunsten des anderen bevorzugt werden sollte privateoder protectedsollte, sollte die Entscheidung darauf beruhen, ob es wahrscheinlicher ist, dass die Enthüllung eines Mitglieds es einer abgeleiteten Klasse ermöglicht, etwas Nützliches zu tun wäre sonst nicht möglich oder würde verhindern, dass zukünftige Versionen einer Klasse ihre internen Datenstrukturen auf eine Weise ändern, die effizienter wäre. Man kann Beispiele für beide Situationen in sehen List<T>.

In einigen Fällen Pointkann es hilfreich sein, Elemente an Ort und Stelle zu aktualisieren , wenn eine Liste von Aggregaten (z. B. Strukturen) vorhanden ist. Wenn List<T>der Hintergrundspeicher abgeleiteten Klassen ausgesetzt wird, kann man leicht eine EditableList<T>mit einer Methode definieren:

delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2);

void ActOnItem<TParam>(int index, ref TParam param, ActByRef<TParam> proc)
{
  .. test index, then...
  proc(ref _arr[index], ref proc);
}

was dann mit so etwas aufgerufen werden könnte:

int adjustmentAmount = ...;
myList.ActOnItem(index, ref adjustmentAmount, 
  (ref Point pt, ref int dx) => pt.X += dx );

Ein solches Verfahren könnte effiziente Aktualisierungen auch bei relativ großen Strukturtypen ermöglichen [da kein Kopieren erforderlich wäre]. Die Tatsache, dass List<T>seine Interna nicht verfügbar gemacht werden, macht es unmöglich, eine Klasse abzuleiten, die einen solchen Operator effizient implementieren könnte.

Auf der anderen Seite, obwohl Microsoft diese Fähigkeit List<T>meines Wissens noch nicht ausgenutzt hat, würde eine private Version des Backing Store es ermöglichen , den Backing Store in Teile aufzuteilen, die bei Verwendung der meisten Daten kleiner als 85 KB waren Typen oder kleiner als 1000 Elemente bei Verwendung double. Eine solche Aufteilung wäre nicht möglich, wenn List<T>der Hintergrundspeicher abgeleiteten Klassen ausgesetzt worden wäre .

Superkatze
quelle
Da Felder standardmäßig privat sind, erwarte ich nicht, dass die Ausgabe der Common Intermediate Language des C # -Compilers von int myFieldund private int myFieldunterschiedlich ist. Daher glaube ich nicht, dass das Hinzufügen von Private für Interpretationen für andere .NET-Sprachen offen bleibt.
Roy T.
@RoyT.: Mein Punkt war, dass bei Verwendung mehrerer Sprachen möglicherweise nicht klar ist, dass ein Mitglied mit einem ausgelassenen Zugriffsspezifizierer den Zugriff haben sollte, der in einer anderen Sprache der Standard gewesen wäre.
Supercat
Ah, ich verstehe jetzt. Sie haben sich so explizit auf andere .NET-Sprachen bezogen, dass ich es als Programme verstand, die nicht verstehen, nicht als Menschen.
Roy T.
1
@ RoyT.: Ich habe den ersten Absatz bearbeitet; macht das das klarer?
Supercat
2

Ja, Sie sollten es verwenden :) Das privateSchlüsselwort wird verwendet, da es allgemein anerkannt ist und alle Zweifel am beabsichtigten Umfang eines Klassenmitglieds beseitigt.

Die Lesbarkeit von Code ist sehr wichtig, insbesondere wenn Sie in einem Team arbeiten. Wenn Sie die Lesbarkeit von Code genauer untersuchen möchten, kann ich Ihnen The Elements of C # Style als gutes Nachschlagewerk empfehlen .

gelegentlichDev
quelle
-4

Frage:

"Sollten Sie jemals private Felder und Methoden in C # verwenden?"

Schnelle Antwort:

Ja, aber das hängt von Ihrer Codelogik ab.

Langweilige erweiterte Antwort:

Ich schlage vor, immer die Sichtbarkeit für Mitglieder anzugeben.

Ich denke, es ist ein guter Ansatz, Mitglieder standardmäßig als "privat" zu deklarieren.

In der realen Welt verwende ich stattdessen "geschützt".

Früher oder später könnte dieses versteckte Mitglied von einer Unterklasse verwendet werden.

Manchmal kann eine gute Frage besser beantwortet werden, indem die entgegengesetzte Frage gestellt wird.

Die entgegengesetzte Frage zu Ihrer Frage könnte etwa so lauten:

"Sollte ich für Felder und Methoden in C # immer den Modifikator" Öffentlicher Zugriff "verwenden?"

In anderen Programmiersprachen können Sie je nach Design öffentlich für die Öffentlichkeit "werben".

Ich verwende viele (visuelle) Steuerungsbibliotheken für tiefe Hierarchien, in denen einige Mitglieder (Eigenschaften, Methoden) erforderlich sind.

Manchmal ist es besser, sie öffentlich zu haben, manchmal nicht.

umlcat
quelle
5
Die Verwendung von protected als Go-to-Spezifizierer kann schlecht sein. Möglicherweise wird die Oberklasse für Manipulationen geöffnet, die möglicherweise nicht geeignet sind, da eine Unterklasse möglicherweise Fehlerprüfungen oder Einschränkungen umgehen kann, die in der Oberklasse eingeführt wurden. Auch wenn dies nicht der Fall ist, werden Unterklassen mit zusätzlichen redundanten In-Scope-Variablen verschmutzt (z. B. bietet eine geschützte Variable mit einem Accessor jetzt zwei Möglichkeiten, sie in einer Unterklasse zu ändern).
2
-1: Versucht nicht, die Frage zu beantworten.
Mattnz
1
Öffentlich und geschützt sind meiner Meinung nach näher als privat und geschützt. Sie sind Teil der Schnittstelle der Klasse. Private Mitglieder sind nur interne Blackbox-Mitglieder.
Petter Nordlander
+1, weil ich gerne privat deklariere, auch wenn es nicht benötigt wird. Bei gutem Code geht es viel um Lesbarkeit und Funktionalität.
PhillyNJ
2
-1 Die Verwendung von protected als Standard ist ein schrecklicher Rat. Sie können die Sichtbarkeit von Mitgliedern später jederzeit erhöhen, jedoch nicht umgekehrt, ohne den Code zu beschädigen (wenn Benutzer Ihren Code verwenden).
Oliver Weiler