C# Kleine Frage zu public Variablen

Cartman999

Lieutenant
Registriert
Aug. 2007
Beiträge
814
Gibt es einen Unterschied zwischen dem Code:
Code:
public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }
        private Vector2 position;
position = new Vector2(100,100);
und diesem Code:
Code:
public Vector2 Position;
Position = new Vector2(100,100);
Oder sind das nur zwei verschiedene Schreibweisen?
Ich möchte eine public Variable erstellen die ich in anderen Klassen nutzen kann.
 
Eben.
Getter Setter (Properties) sind üblicher als eine Variable Public für jede Klasse zu machen.
Zu dem auch sicherer.
 
Getter und Setter sind hauptsächlich in Java sinnvoll (weil man nur so ggf. Nebeneffekte haben kann). In C# spricht aber nichts gegen ein Public member. Ist in C# auch kein schlechter Stil (in anderen Sprachen dagegen schon).
 
Häufig will man nicht nur eine Variable ändern, sondern die interne Struktur der Klasse (und evtl. weiterer Klassen), das geht in Java nur mit einer Methode und nicht mit einer direkten Zuweisung einer Variable.
Wenn ich ein Member direkt exponiere, müsste ich die API ändern, um Seiteneffekte zu haben.
Dagegen ist die zugriffsweise in C# für Getter/Setter (in C# Properties) und public Member genau gleich (z.B. einfach "MyVar"). Ebenfalls kann ich ggf. Seiteneffekte einfach einfügen.

Und noch was spezielles zu Java. Ich hatte schon oft den Fall, dass ich einfach nur eine Variable ändern wollte. Korrekterweise hab ich dann einen Setter und Getter deklariert. Schön fand ich das aber nie. Ist eine Menge Code (und Javadoc), ohne das dabei viel Semantik innewohnt. Nicht gegen Java (ich mag die Sprache), aber das wurde bei C# besser gelöst.

Daher: Man verliert nichts (vs. in Java Seiteneffekte oder Api-Change), und hat weniger und übersichtlichen Code.
 
@misu: Entweder sind hier die Begrifflichkeiten etwas durcheinander oder ich kann dir ganz und gar nicht zustimmen. Genau so wie man in Java den internen Zustand von Objekten mittels getter/setter-Methoden kapselt, so verwendet man in C# Properties dafür (welche hier im Thread ebenfalls als getter/setter bezeichnet wurden).

In C# spricht aber nichts gegen ein Public member. Ist in C# auch kein schlechter Stil (in anderen Sprachen dagegen schon).

Natürlich sind public member schlechter Stil (oder besser gesagt public fields, Member können ja auch Methoden sein). Sobald du Properties einsetzt, hast du aber keine public fields mehr, denn Properties sind Properties und keine Felder (Attribute in C#).

Häufig will man nicht nur eine Variable ändern, sondern die interne Struktur der Klasse (und evtl. weiterer Klassen), das geht in Java nur mit einer Methode...

Wie ist das gemeint? Du kannst maximal den internen Zustand (nicht Struktur) eines Objekts (nicht Klasse) ändern.
 
Zuletzt bearbeitet:
Member können ja auch Methoden sein
Genau das ist mein Punkt. In Java und vielen anderen Sprachen können Member eben keine Methoden sein. In C# aber schon. Daher machts keinen Sinn, alles als Property zu Kapseln. Das ist einfach unnötig. (Public fields sind nach wie vor schlecht.)
Du kannst maximal den internen Zustand (nicht Struktur) eines Objekts (nicht Klasse) ändern.
Unsauber formuliert meinerseits, es geht natürlich um den Zustand.
 
Wenn ich die Variable Position in einer anderen Klasse nutzen würde dann hätte sie doch immer den gleichen Wert, egal welche der beiden Möglichkeiten ich nutzen würde, oder?
Zum Beispiel: Vector2 Neue Position = Klasse1.Position;
 
@misu

Kann deine Aussage leider immer noch nicht nachvollziehen, könntest du bitte ein Beispiel posten? :)

Genau das ist mein Punkt. In Java und vielen anderen Sprachen können Member eben keine Methoden sein.

Vielleicht reden wir hier aneinander vorbei, aber "Class members" im Allgemeinen beschreiben gleichermaßen Attribute (data members) als auch Methoden (member functions), egal ob in C# oder Java.

Daher machts keinen Sinn, alles als Property zu Kapseln ... Public fields sind nach wie vor schlecht.

Was denn nun :confused_alt:
edit: ALLES als Property zu kapseln macht in der Tat weniger Sinn, sondern nur dass, was nach außen angeboten werden soll. Aber das ist wohl nicht das, worauf wir hinaus wollten.
 
Zuletzt bearbeitet:
Code:
//schlecht, ünnötig viel Code, wenig Semantik

/*
 *
 */
public void setVariable(int newValue) {
   this.variable = newValue;
}


/*
 *
 */
public int getVariable() {
   return this.variable;
}

/*
*
*/
private int variable;
Das ist die korrekt Java-Variante.
Code:
/*
*
*/
public Int32 Variable;
Das ist die korrekte C# Variante unter der Voraussetzung, dass keine Seiteneffekte erwünscht sind. Ansonsten:
Code:
private double variable;

public double Variable
{
    get { return this.variable; }
     set { variable = value; }
}
Dabei stellt die letztere Variante keinen API-Change dar.

Begriffliches:
Properties sind Accessoren.
Data Member, Member, Fields sind für mich eigentlich dasselbe. (Variiert auch ein bisschen mit den Sprachen.)

@Carmann: Ja. Du kannst halt bei deiner ersteren Variante ggf. noch im get/set-Block weitere Dinge berechnen.
 
Also irgendwie kann ich eurer kleinen Unterhaltung nicht folgen, insbesondere nicht misu ;)

Cartman999 schrieb:
Gibt es einen Unterschied zwischen dem Code:
Code:
public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }
        private Vector2 position;
position = new Vector2(100,100);
und diesem Code:
Code:
public Vector2 Position;
Position = new Vector2(100,100);
Oder sind das nur zwei verschiedene Schreibweisen?
Ich möchte eine public Variable erstellen die ich in anderen Klassen nutzen kann.

Wurde hier ja schon geschrieben. Ersteres ist ein Property. In deinem Beispiel mit "Backingstore" (private Vector2 position). Das andere ein "public field". Der Code aus deinem ersten Beispiel entspricht einem simplen Property, dass du auch als
Code:
public Vector2 Position { get; set; }
schreiben kannst.

Da hier schon der Vergleich mit Java erbracht wurde: die Getter/Setter-Methoden aus Java sind im Grunde identisch zu Properties. Diese schreibweise ist nur Eye-Candy. Intern werden ebenfalls Getter- und Setter-Methoden erzeugt.

Der Grund wieso öffentliche Felder "verpönt" sind, ist recht simple.
Zum einen hast du keine Möglichkeit irgendeine Logik, z.B. Validierung von Werten, darauf anzuwenden. Wenn irgendwer meint, er müsse jetzt Wert X darin speichern, dann ist das so. Bei einem Property kannst du den Setter deinen Bedürfnissen anpassen.
Ein weiteres Beispiel wäre die Möglichkeit benachrichtigt zu werden, wenn sich der Wert geändert hat. Ohne diese Benachrichtigungen wäre das Data-Binding gar nicht möglich.

Weiterhin kannst du mit Properties deutlich besser kapseln. Ein veröffentlichtest Feld ist für jeden lesbar und schreibar. Zwar hast du die Möglichkeit das Feld mit readonly zu maskieren, aber dann kannst du es selber auch nur aus dem Konstruktor bearbeiten.
Bei einem Property kann der Getter public sein, während für den Setter internal, private oder protected verwendet wird.
 
misu schrieb:
Das ist die korrekt Java-Variante.

Korrekt, da bin ich bei dir.

misu schrieb:
Das ist die korrekte C# Variante unter der Voraussetzung, dass keine Seiteneffekte erwünscht sind.

Nein, das ist eben nicht empfehlenswert. Du verwendest dort ein public field.

public String Var ist nicht das gleiche wie public String Var {get;set;}. Letztere Version (Auto-Implemented Properties) ist das absolute Minimalbeispiel für Schreibfaule, welche technisch deiner ausführlichen Variante gleichkommt, ohne dass man sie explizit hinschreiben muss.

Public Fields und Properties sind nicht austauschbar ("Synonyme"), da sie nicht das selbe sind. Reflection funktioniert auf Properties anders als bei Variablen, du kannst mit Variablen kein Databinding machen (mit Properties schon), XML-Serialisierung steht auf Properties und der out-Parameter tut auch nicht. Außerdem kannst du mit Gettern/Properties lazy initialization realisieren und so weiter und so fort.
 
Zuletzt bearbeitet:
Code:
public String Var {get;set;}
Stimmt, hast du recht. Bin grade beruflich auf Java fixiert, hatte das vergessen.
 
Leute letztendlich ist Property (public int Var {get;set;}) nichts anderes als die Java Version. Nach dem der Code compiliert wurde, könnt ihr euch selbst davon überzeugen, dass es ein public int getVar() und public int setVar(int value) methoden gibt.

An sich macht Property nur dann sinn, wenn man vor dem get oder set was macht (Validierung, etc). Macht man es nicht sollte man auf Field setzen. Ein Methodenaufruf kostet mehr Zeit als eine Variable.
 
Die Zeit ist fast Banane bei Programmen, die in einer Runtime ausgeführt werden, wie zB Java und C#. Da ist eh nix mehr zu retten. ;)
 
roker002 schrieb:
An sich macht Property nur dann sinn, wenn man vor dem get oder set was macht (Validierung, etc). Macht man es nicht sollte man auf Field setzen. Ein Methodenaufruf kostet mehr Zeit als eine Variable.
Das ist aber extrem Kurzsichtig. Bei einem Property hält mich nichts davon ab noch nachträglich zusätzliche Funktionalität hinzuzufügen ohne, dass der Aufrufer was davon merkt. Wenn ich ein Feld habe ist das plötzlich ein Breaking Change.

Und nur wegen der Geschwindigkeit auf Felder zu setzen ist in 99,9% der Fälle ein Musterbeispiel für premature Optimization.
 
TheCadillacMan schrieb:
Und nur wegen der Geschwindigkeit auf Felder zu setzen ist in 99,9% der Fälle ein Musterbeispiel für premature Optimization.

Dann erklär mir bitte, wozu du ein Property brauchst wenn du eh nur getter und setter und keine andere Funktionalität hast? Es gibt sicher in Einigen Bereichen, wie CLR wo man auf die Variablen nicht zugreifen kann, weil diese als Field implementiert worden sind. Dann verstehe ich es schon. Ich verstehe auch, wenn man einen Event auf Setter setzt um zu signalisieren, dass der Wert sich geändert hat. Oder man will nur den eine Variable als Schreibgeschützt setzen und intern aber volle Lese- und Schreibrechte haben.
public int Var{ get; private set;}
Aber wenn nichts davon zutrifft, wieso sollte ich Property benutzen?

Und das mit premature optimization ist nur eine Ansichtssache. Ich habe nie behauptet, dass ich wegen der Perf auf Field setze. Ich wollte nur sagen, dass ein Methodenaufruf einfach mehr Rechenzeit kostet. Sag mir einfach, was schneller ausgeführt wird: eine While Schleife oder Rekursive aufrufe?
 
Zuletzt bearbeitet:
Naja, ich würde das nicht so extrem sehen. Der Vorteil von Property statt Field ist nicht sooo groß, in vielen Sprachen werden auch tatsächlich die Fields exponiert (z.b. Python).
Einige Vorteile:
- Man kann noch nachträglich Seiteneffekte einbauen (sonst Api-Change)
- Man hat eine einheitliche Api auf Fields mit und ohne Seiteneffekte
- Es praktisch keine Performance kostet. Je nach Sprache und Compiler werden Getter/Setter/Properties inlined
- Es in der Sprache gängig ist, und man damit den gleichen Stil wie alle anderen Programmierer hat (Konsistenz)
 
Zurück
Oben