C# Getter + Setter, Public vs. Private: (Schwach)sinn?

Ok danke, kurze Frage dann zum Abschluss, einfach mal so theoretisch, hat sich so ergeben aufgrund der Antworten:
Wieso hat man dann überhaupt die Möglichkeit Variablen public zu deklarieren?
Würde bedeuten, dass man es irgendwann ja bräuchte.

Und:
Getter und Setter bei Variablen, die nach Außen in keinster Weise zugänglich gemacht werden sollen? Also private Getter und Setter? Praktisch nur, wenn irgendwas dazwischen laufen muss zur Regelung, oder?
 
Zuletzt bearbeitet:
public dient beispielsweise für final-variablen

festwerte, die den eigenen methoden als parameter mitgeliefert werden

new Color(Color.WHITE);


2te Frage:
Ansichtssache!
Wenn du dein Code änderst, musst eventuell refactoren, da du evtl. doch noch nen paar Zeilen vor dem Schreiben/Lesen der Variable eingefügt hast und das sicherlich nicht an 100 Stellen einzeln nachholen willst.
 
Zuletzt bearbeitet:
@Rossibaer:

Hut ab, echt gut beschrieben!!! Ich bin leider kein so guter Erklärbär. Aber bin ja auch noch fleißig am lernen. :D
 
Also zum Zusammenfassen:

Anstatt einfach public, lieber das hier:

Code:
        public string bla { get; set { if (value != null) this.bla = value; } }

Bitte im nächsten Post unterschreiben. ^^

EDIT:
Nee das geht nicht, sorry. -.-
Totaler Syntaxmüll. :D
Gibt es nicht irgendeine Schnellschreibweise oder sowas, weil das den Gesamtcode ja verlängern würde bis zum gehtnichtmehr bei einer entsprechend großen Klasse, wenn man das jedesmal so schreiben müsste:
Code:
public class BaseClass 
{
   private string name;
   public string Name
   {
      get 
      {
         return name; 
      }
      set 
      {
         name = value; 
      }
   }
}
Irgendjemand sagte was von 2xTab?

Das wäre sonst so unnötig lang, dass ich dann am besten mit Regions alles übersichtlich halten möchte. Ist ja dann praktisch von der Haltung umständlicher als ein Haustier. :p
 
Zuletzt bearbeitet:
Schreibs halt so:
Code:
private string mName;
public string Name { get { return mName; } set { mName = value; } }
oder so:
Code:
private string mName;
public string Name
{
    get { return mName; }
    set { mName = value; }
}
oder schliess das Property im VS:
Code:
private string mName;
public string Name...

Das wird alles von "Format Document" unterstützt (Ctrl+E,D).
 
Das mit 2x Tab ist einfach.

schreib "prop", dann erscheint in VS prop, drückst 2x Tab und dann hauste noch den Namen rein und hast ein Standardproperty
 
m ist der präfix für membervariablen einer klasse/struktur. in vc++ 6 war es noch m_.
 
Witzig, das hab ich mir eigentlich nirgends abgeguckt, bedeutet aber genau das. Innerhalb von Methoden schreibe ich vor die Variablen ein 'v'. Und wenn es sich um Methodenparameter handelt ein 'p'. Das ist "meine Konvention". :)
 
Der Präfix m_ hat nichts mit C++ oder C# zu tun. Es handelt sich ausschließlich um eine Konvention, die auch völlig anders gewählt werden kann.
Unter C++ war die Ungarische Notation recht geläufig.

Im Übrigen hab ich dem Thema zu public/private und den Gettern und Settern auch nochwas hinzuzufügen.
Meiner Ansicht nach sind Aspekte wie "Schönheit" und Übersichtlichkeit des Codes an dieser Stelle nicht vorrangig.

Die bei weitem wichtigsten Vorteile liegen in der Wartbarkeit des Codes:
1) Arbeiten an einem Projekt mehrere Leute, so kann es durch schlechte Absprachen (Daily business!) dazu kommen, dass Instanzvariablen von außen in einer Weise verändert werden, die zu unerwünschten Effekten führen kann (auch Bugs benannt).
2) Eine Klasse kann komplett durch eine andere Implementierung ersetzt werden, wenn die Schnittstellen gleich heißen. Greifst du direkt auf einzelne Instanzvariablen zu, ist diese Möglichkeit stark eingeschränkt.
Eine Klasse soll eine Funktion zur Verfügung stellen, und nicht eine konkrete Implementierung!!
3) Will man eine Klasse nachträglich ändern, kann es erforderlich sein, beim Setzen von Instanzvariablen spezielle Aktionen auszuführen, die vorher nicht nötig waren. Ohne Setter würde das dazu führen, dass sehr viel Quellcode reviewed werden muss, um überhaupt Stellen zu finden, an denen zusätzlich etwas geändert werden muss. Sehr hässlich!

Übrigens ist es nicht zwingend nötig oder sinnvoll für jede private Variable einen Getter oder Setter anzubieten.
 
Zuletzt bearbeitet:
Cyba_Mephisto schrieb:
Wieso hat man dann überhaupt die Möglichkeit Variablen public zu deklarieren?
Würde bedeuten, dass man es irgendwann ja bräuchte.
Weils Java auch so macht(* SCNR*). ;) Vermutlich aus Bequemlichkeit und weil es schneller ist. Wenn man direkt auf eine öffentliche Variable zugreift, spart man sich einen Methodenaufruf. Aber nötig ist das nicht.

Nochmal allgemein etwas zu den öffentlichen/privaten Variablen: Das Hauptproblem bei öffentlichen Variablen bei Sprachen wie C# ist, dass man sie nicht transparent durch getter/setter/Properties ersetzen kann(weil sich dadurch das Interface der Klasse ändert). Deswegen bleibt einem nichts anderes übrig, als *immer* Properties/getter/setter zu verwenden, es sei denn man hat Spaß daran, seinen Code zu umzuschreiben.

Dass immer setter UND getter gefordert werden ist hingegen wenig sinnvoll(bei einer property deren Rückgabewert dynamisch bei jedem Aufruf berechnet wird, einen setter zu fordern ist unsinnig).
Code:
    private int a, b;
    public int sum { get { return a + b }; set { /* ja was soll hier denn rein? */ }; }
 
Zuletzt bearbeitet:
IceMatrix schrieb:
Der Präfix m_ hat nichts mit C++ oder C# zu tun. Es handelt sich ausschließlich um eine Konvention, die auch völlig anders gewählt werden kann.
Unter C++ war die Ungarische Notation recht geläufig.
ja natürlich. ich hab es zumindest zum ersten mal in vc++ 6.0 wirklich umgesetzt gesehen. und von daher hab ich das mit member-variablen her, was ich mittlerweile auch selbst so umsetze (bei funktionen mit gleichem parameter- wie instanzvariablennamen immer this->test = test; zu schreiben nervt auf dauer).
und danke für den link. davon hab ich schon mal was gehört aber anscheinend wieder verdrängt. jetz kann ich endlich mal entschlüsseln, was alle präfixe bedeuten. :)
 
Darii schrieb:
[...] Dass immer setter UND getter gefordert werden ist hingegen wenig sinnvoll(bei einer property deren Rückgabewert dynamisch bei jedem Aufruf berechnet wird, einen setter zu fordern ist unsinnig).
Code:
    private int a, b;
    public int sum { get { return a + b }; set { /* ja was soll hier denn rein? */ }; }

Na ja, es gehört zum guten Stil den Setter mit zu setzen, auch wenn er leer wäre... Weil selbst wenn er leer wäre wird er auf private gesetzt, denn so ist er dann auch nicht von außen sichtbar. Desweiteren sollten Properties groß geschrieben weden.

Was ich meine ist das hier:
Code:
    private int a, b;
    public int Sum 
    {
        get { return a + b; }
        private set;
    }
 
HaGGi.13 schrieb:
Weil selbst wenn er leer wäre wird er auf private gesetzt, denn so ist er dann auch nicht von außen sichtbar.
Das ist so total unsinnig. Es gaukelt dir durch die Signatur der Klasse vor, dass du diesem Property etwas zuweisen kannst (kannst du intern ja auch), aber es passiert damit nichts. In dem Fall lasse ich den Setter immer weg. Der Kompiler meckert dann, wenn man dem Property etwas zuweist.
 
HaGGi.13 schrieb:
Na ja, es gehört zum guten Stil den Setter mit zu setzen, auch wenn er leer wäre... Weil selbst wenn er leer wäre wird er auf private gesetzt, denn so ist er dann auch nicht von außen sichtbar.
Das ist kein guter Stil, das ist überflüssig bis irreführend. Private ist nicht dafür da, Methoden zu kennzeichnen, die nicht gebraucht werden. Du implementierst ja auch nicht sämtliche Interfaces die du kennst und setzt die Methoden auf private weil du sie nicht brauchst oder sie unsinnig wären.
 
Prinzipiell würde ich das Interface einer Klasse als einen Vertrag mit der Außenwelt ansehen. In diesem Vertrag stehen nur die Dinge, die auch tatsächlich von der Klasse angeboten werden und erhältlich sind. Wenn ich aber in das .Net Framework reinschaue, so finde ich viele Klassen, die zwar nach außen vortäuschen, sie würden eine Leistung anbieten, aber im Inneren tut sich dann nichts oder schlimmer sie lösen diese NotSupported oder NotImplemented Exceptions aus. Wie letzten Endes jemand seine Klassen designed, bleibt jedem selbst überlassen. MS scheint sich da auch nicht so eins zu sein ob sie die Getter/Setter immer oder nur dann wenn notwendig anbieten. Ich würde für meinen Teil jedoch nur das anbieten, was ich auch in der Lage bin in der Klasse zu leisten. Wenn ich später doch einen Setter für die Eigenschaft brauche, kann ich ja später auch ohne Probleme diesen Setter ergänzen. Für bereits vorhandenen Code, der diese Eigenschaft verwendet, sollte das unerheblich sein, da er zu diesem Zeitpunkt nur den Getter nutzen konnte und keine Ahnung über den Setter hatte. Das erspart mir zum einen "toten" Code (siehe Antipatterns), zum anderen können die Anwender/Programmierer auch nach dem Prinzip WYSIWYG die Klasse verwenden. Desweiteren bewahre ich mir das KISS (Keep It Simple Sissi!) Paradigma.
 
So habe mich jetzt mal hingesetzt und mein Projekt zum Großteil so neugeschrieben bzw. verbessert.
Fühle mich nur irgendwie total unzufrieden damit, meiner Meinung nach ist dadurch alles unübersichtlicher geworden. Naja was heißt unübersichtlich, dass Zeug steht im Weg und nervt momentan einfach. Die Dinger mit "m" und ohne, naja wie soll ich das sagen, es wirkt irgendwie falsch auf mich weil praktisch alles "doppelt" dasteht.

Ich hab´s jetzt auch mal so interpretiert, dass ich dann klassenintern direkt auf die Member anstatt die Properties zugegriffen habe. Ich gehe mal davon aus, dass es so vertretbar ist?
 
Ein Tipp am Rande, ich würde Getter und Setter immer ans Ende einer Klassenimplementierung packen, so weißt du, dass der Code der was anstellt immer als erstes kommt.
 
Gobble-G schrieb:
Das ist so total unsinnig. Es gaukelt dir durch die Signatur der Klasse vor, dass du diesem Property etwas zuweisen kannst.

Und ob das sinn macht , Properties wurden eingefuehrt damit man immer den gleichen Attributwert erhaelt, so soll auch innerhalb einer Klasse mit dem Property gearbeitet werden. (Eben damit evtl. Notwendige anderungen erledigt werden koennen, sollte es notwendig werden das Attrubute vor dem zugriff zu aendern muss nur an einer Stelle was geandert werden im Get. Natuerlich kann der Entwickler auch direkt auf das member zugreifen, nur muss er sich sicher sein das das auch immer so ok ist) -> Schaut euch mal ein Typed DataSet an ;)

Darii schrieb:
Das ist kein guter Stil, das ist überflüssig bis irreführend. Private ist nicht dafür da, Methoden zu kennzeichnen, die nicht gebraucht werden. Du implementierst ja auch nicht sämtliche Interfaces die du kennst und setzt die Methoden auf private weil du sie nicht brauchst oder sie unsinnig wären.


:rolleyes: Bei der Implementierung von Interfaces muessen alle vom Interface deklarierten Methoden Public implementiert werden -> wenn nicht gibts nen Compilererror. Ausserdem dienen Interfaces dazu immer ein Minimum an Funktionalitaet bereitzustellen/sicherzustellen.

Private wird benutzt um eben zu verhindern das Attribute wilkuehrlich von aussen gesetzt werden koennen (aber eben auslesen zu koennen), bei methoden wird es verwendet weil Methoden nicht willkuehrlich von aussen aufgerufen werden sollen.

Code:
 private int a;
    public int A
    {
        get { return a; }
        private set;
    }
Auch finde ich diese Konvention gut , da hier Klar ist das der Entwickler den Setter absichtlich nicht zulaesst.

Code:
// gibt den wert von A zurueck
// Nur lesend
 private int a;
    public int A
    {
        get { return a; }
    }
So ist es auch ok! Es wird dann immer klar was gewollt ist, Kommentare sind ohnehin pflicht ;)
Ich mache es nach methode 1, weil so sehr leicht auch der setter freigegeben werden kann. (Property wird von VS erstellt.)

Was genau daran Irrefuehrend ist kann ich nicht nachvollziehen, es gibt hunderte Beispiele aus dem Framework und es ist egal wie Du es implementierst, muss jeder fuer sich entscheiden. Beides ist ok
 
Zuletzt bearbeitet:
@olampl: /sign :D
 
Zurück
Oben