2015-07-16 7 views
7

Ich habe gerade angefangen, C# zu lernen, und ich habe ein wenig mit der Getter und Setter Stenografie zu kämpfen.{bekommen; Set;} und Zugriffsmodifikatoren

Wie ich es verstehe, sind die beiden folgenden Methoden gleichwertig. Ist das richtig?

//Method 1 
public string name { get; set; } 

//Method 2 
private string name 
public string getName() { return name;} 
public string setName(string newName) { this.name = newName; } 

Zweitens: Wie funktionierts wenn wir unterschiedliche Zugriffsmodifikatoren auf dem Getter/Setter und die Instanzvariable wollten. Die folgenden Codefehler, die mir sagen, dass der Accessor restriktiver als die Eigenschaft sein muss und dass ich keine Modifikatoren für Stören-Accessoren angeben kann. Kann jemand bitte klarstellen?

private int maxTime { public get; public set; } 

EDIT: Um zu klären, habe ich kein bestimmtes Ziel, nur um zu verstehen. Ich verstehe nicht, was diese Kurzschreibweise macht. In anderen Sprachen hatte ich private Instanzvariablen und verwendete öffentliche Getter und Setter, um diese Instanzvariablen zu verwalten. Es erlaubt dies, wenn ich die Methoden selbst schreibe, aber nicht mit dieser Kurzschreibweise. Warum ist das?

EDIT2: Eine letzte Frage, um mein Verständnis zu überprüfen. Die beiden folgenden Codefragmente verwenden Eigenschaften zum Verwalten der Variable maxTime. Der einzige Unterschied zwischen den beiden ist Stil. Ist das richtig?

private int maxTime; 
public int MaxTime{ get; set; } 

vs

private int maxTime; 

public int MaxTime 
{ 
    get { return maxTime; } 
    set { maxTime= value; } 
} 
+2

Warum möchten Sie öffentliche Getter/Setter auf eine private Variable? –

+1

Nein, diese beiden Ansätze sind nicht gleich. Erklären Sie, was Sie tun möchten, nicht nur, mit welchem ​​Code Sie am Ende waren. – CodeCaster

+0

Sie können nicht _private int maxTime {public get; öffentliches Set; } _ als der äußere Zugriff für die Eigenschaft (keine Variable!) ist restriktiver als die innere. Sie könnten _public int maxTime {private get; einstellen; } _ - HINWEIS public modifier nicht erforderlich für set – PaulF

Antwort

13

Statt der falschen private int maxTime { public get; public set; }, Sie eine Eigenschaft schreiben können, die ein privates Feld bevölkern:

private int maxTime; 

public int MaxTime 
{ 
    get { return maxTime; } 
    set { maxTime = value; } 
} 

Dies ist nützlich, wenn Sie Logik anwenden möchten, wenn Abrufen oder Festlegen des Werts von MaxTime. wenn nicht, wird eine einfache Kurzschrift-Eigenschaft tun:

public int MaxTime { get; set; } 

Sie eine Eigenschaft erstellen, die einen öffentlichen Getter aber einen privaten Setter haben, wie folgt aus:

public int MaxTime { get; private set; } 

Dies ist nützlich für Nur-Lese-Eigenschaften und Normalerweise wird die Eigenschaft im Konstruktor der Klasse aufgefüllt.

Sie können sogar eine Eigenschaft erstellen, wo der Setter öffentlich ist, aber der Getter ist privat, obwohl ich mir kein Szenario vorstellen kann, das wäre nützlich.Darüber hinaus fordern Code-Standards, dass so etwas eine Methode und keine Eigenschaft sein sollte. (read this)

public int MaxTime { private get; set; } 

Die Antwort Ihre Frage in bearbeiten 2 nein.

der erste Code ändern nie die private int maxTime, während der zweite tut. Wenn Sie innerhalb Ihrer Klasse jedoch nur die Eigenschaft MaxTime verwenden, sind sie funktional gleichwertig.

Update:

Seit 6 C# können Sie Kurzschrift-Eigenschaften ohne Setter schreiben:

public int MaxTime {get;} 

Diese Eigenschaften können nur im Konstruktor initialisiert werden, oder hart wie folgt codiert: (auch ein neues Feature 6) von C#

public int MaxTime {get;} = DateTime.Now; 

Dies ist nützlich für unveränderliche Eigenschaften (im Gegensatz zu Nur-Lese-Eigenschaften, der Wert einer solchen Eigenschaft kann nicht einmal in der Hosting-Klasse ändern auf ce initialisiert.

+0

Also in Ihrem zweiten Code-Snippet, sind sowohl das Holen und setzen öffentlich? – JShell

+0

Ja. Sofern für den Getter oder Setter kein restriktiverer Zugriffsmodifikator angegeben wird, verfügen beide über den Modifikator für den Zugriff auf die Eigenschaft. –

+0

Also, was ist der Unterschied zwischen einer Eigenschaft und einer Reihe von Methoden, die das Abrufen/Einstellen behandelt? Ist es einfach Sprache? – JShell

6
//Method 1 
public string name { get; set; } 

//Method 2 
public string name 
public string getName() { return name;} 
public string setName(string newName) { this.name = newName; } 

2 Die obigen Verfahren sind nicht äquivalent.

Es wäre genauer, sie so vergleichen:

//Method 1 
public string name { get; set; } 

//Method 2 
private string name; // this is private, not public. 
public string Name // this is a property, not a method. 
{ 
    get 
    { 
     return this.name; 
    } 
    set 
    { 
     this.name = value; 
    } 
} 

Und wenn Sie wollen mit Zugriffsmodifikatoren spielen, wie die get öffentlich machen, und die set privat, dann würden Sie es wie folgt tun :

public int maxTime { get; private set; } 

Weitere Informationen über Auto-Implemented Properties und die Compiler Magie, die hinter den Kulissen weitergeht.

+0

Also, nach einer schnellen Google-Suche, verstehe ich Eigenschaften ein wenig. Aber was ist der Zweck? Wie unterscheiden sie sich von einer Methode, die einfach ein Feld setzt oder bekommt? – JShell

+0

Sieht niedlicher aus als eine Menge von getX() und setX() Methoden – loli

+1

@Jesse: http://StackOverflow.com/Questions/601621/properties-VS-Methods – sstan

3
public string name { get; set; } 

Was Sie haben, ist Auto-Implemented property, die ein Stütz privaten Bereich intern haben würde (und Zeit Methoden für get/set kompilieren).

In C# -Code dies wäre gleichbedeutend mit:

private string _name; 
public string name 
{ 
    get { return _name; } 
    set { _name = value; } 
} 

Beim Kompilieren, get/set in Methodenaufrufe umgewandelt, etwas ähnlich dem, was Sie haben.

Für:

private int maxTime { public get; public set; } 

Der Fehler ziemlich klar ist, können Sie weniger restriktive Zugriffsbezeichner nicht als das Objekt selbst. Zum Beispiel, wenn Sie Ihre public Eigenschaft wollen eine publicget haben, aber wenn Sie die Eigenschaft Einstellung von innerhalb der Klasse ermöglichen, wollen Sie tun können:

public int maxTime { get; private set; } 

Sie sollten auch sehen: .Net Naming conventions, wäre es Besser, wenn Sie dem folgen, so dass Sie Ihren Eigentumsnamen mit einem Großbuchstaben beginnen lassen können.

2

Die erste Methode ist einfach C# syntaktischer Zucker für eine automatisch implementierte Eigenschaft. Es bietet eine Implementierung der entsprechenden Accessoren, wenn Sie es kompilieren.

Das zweite Beispiel ist anders. Hier haben Sie ein public-scope-Feld (normalerweise ein no-no wegen des Kapselungsprinzips) und zwei Methoden, die auf die Variable zugreifen. Es gibt einen subtilen Unterschied in der semantischen Verwendung; Normalerweise werden Eigenschaften verwendet, um den Zustand zu exponieren, während eine Methode normalerweise anzeigt, dass die Methode einige Berechnungen hinter sich hat und nicht nur den aktuellen Zustand zurückgibt oder ändert (auch dies ist eine Konvention, keine harte Regel). Methoden werden normalerweise mit der Benennung von VerbAction (public Thing GetAThing() {}) formatiert.

Automatisch generierte Eigenschaften können unterschiedliche Zugriffsmodifizierer haben, müssen aber nur das Get oder Set weniger zugänglich machen als den Gesamtmodifikator.

public int X { get; private set; } // OK 
public int X { private get; set; } // OK 
private int X { public get; public set; } // NOT OK 
+1

Wenn Sie sagen, dass Methoden normalerweise mit der VerbAction-Benennung versehen werden, würde etwas nicht besser für eine Eigenschaft geeignet sein? – JShell

+0

Ja, aber es gibt Situationen, in denen Methoden auch etwas zurückgeben. Ich nehme die Konvention an, dass eine Eigenschaft, die getting ist, einfach einen Zustand zurückgibt, ohne dabei viel zu tun, während eine Methode die Ergebnisse von etwas rechenintensiv zurückgibt. Ich stimme zu, es ist eine Grauzone und offen für Konvention. – Matt

1

Wenn Sie eine Eigenschaft wie in Methode 1 verwenden (public string Name {get; set;}), der Compiler generiert automatisch einem privaten Träger String-Variable und öffentliche Getter und Setter-Methoden.

Die allgemeine Idee besteht darin, Felder privat zu machen und den Zugriff nur über öffentliche Getter/Setter-Methoden zu erlauben. Wenn Sie also Methode 2 verwenden, deklarieren Sie die Variable privat.

Ich würde empfehlen, ILDASM zu verwenden, um die generierte IL zu lesen, es hilft zu sehen, was unter der Haube vor sich geht.

Der zweite Fehler ist einfach, was der Compiler sagt. Die Sichtbarkeit der Konstrukte muss konsistent sein

Verwandte Themen