2013-06-21 4 views
7

Muss ich eine Variable auf Klassenebene deklarieren, um eine Eigenschaft zu speichern, oder kann ich einfach auf self.{propertyname} im Getter/Setter verweisen?C# Eigenschaft Setterkörper ohne Deklaration einer Eigenschaftsvariablen auf Klassenebene

Mit anderen Worten, kann ich das tun? (Wo ich nicht mongoFormId überall definiert):

public string mongoFormId 
{ 
    get 
    { 
     return this.mongoFormId; 
    } 
    set 
    { 
     this.mongoFormId = value; 
     revalidateTransformation(); 
    } 
} 
+0

Hängt davon ab, wo ist der Code, den du geschrieben hast? – Mike

+3

Sie werden einen Stackoverflow mit diesem Code bekommen :) – NibblyPig

+0

+1 StackOverflowException – meorfi

Antwort

12

Sie können entweder die automatische Zugriffsmethoden verwenden oder Ihre eigenen implementieren. Wenn Sie automatische Zugriffsmethoden verwenden, generiert der C# -Compiler ein Backing-Feld für Sie, aber wenn Sie ein eigenes implementieren, müssen Sie manuell ein Backing-Feld angeben (oder den Wert auf andere Weise behandeln).

private string _mongoFormId; 

public string mongoFormId 
{ 
    get { return this._mongoFormId; } 
    set 
    { 
     this._mongoFormId = value; 
     revalidateTransformation(); 
    } 
} 

UPDATE: Da diese Frage gestellt wurde, C# 6.0 freigegeben wurde. Aber selbst mit der new syntax options gibt es immer noch keine Möglichkeit, einen benutzerdefinierten Setter-Körper zur Verfügung zu stellen, ohne explizit ein Backing-Feld deklarieren zu müssen.

3

Sie benötigen einen Feldvariable zu setzen und den Wert dort speichern, wenn du gehst, benutzerdefinierten Getter und Setter verwenden.

Mit dem Code, den Sie gerade haben, werden Sie in eine Stapelüberlauf-Ausnahme geraten. Wenn Sie mongoFormId etwas zuweisen, führen Sie die Zeile this.MongoFormId = value; aus. Dies ist eine Zuweisung an mongoFormId, was zur Ausführung der Zeile this.MongoFormId = value; usw. führt. Es wird niemals aufhören.

Der richtige Weg ist ein Feld:

private string _mongoFormId; 
    public string mongoFormId { 
     get { return this._mongoFormId; } 
     set { 
      this._mongoFormId = value; 
      revalidateTransformation(); 
     } 
    } 
2

Sie sollen einen Träger Variable haben. Werfen Sie einen Blick:

get { return this.mongoFormId; } 

Wird das Getter auf mongoFormId nennen, was wiederum diesen Code zu nennen, und wieder und wieder! Wenn Sie eine Sicherungsvariable definieren, vermeiden Sie den unendlichen rekursiven Aufruf.

0

prüfen MSDN Properties Overview

Während eine Eigenschaftsdefinition umfasst in der Regel ein eigenes Datenelement, ist dies nicht erforderlich. Der get-Accessor konnte einen Wert ohne zurückgeben, der auf ein privates Datenelement zugreift. Ein Beispiel ist eine Eigenschaft, deren Methode die Systemzeit zurückgibt. Eigenschaften ermöglichen das Verstecken von Daten, die Accessor-Methoden verbergen die Implementierung der Eigenschaft.

0

Dies wird nicht funktionieren, da Sie einen rekursiven Aufruf der Eigenschaft erhalten. Wenn ich mich nicht irre, wird das Ergebnis ein StackOverflowException sein. Sie müssen eine Variable verwenden.

private string mongoFormId; 
    public string MongoFormId 
    { 
     get 
     { 
      return this.mongoFormId; 
     } 
     set 
     { 
      this.mongoFormId = value; 
      revalidateTransformation(); 
     } 
    } 

Wenn Sie nicht revalidateTransformation auszuführen haben, können Sie die Auto-Eigenschaft verwenden. Dies wird eine Hinterlegung für Sie hinter der Szene erstellen.

public string MongoFormId { get; set; } 
0

Mit dem Code, den Sie geschrieben, erstellen Sie eine rekursive Endlosschleife sowohl auf der get und eingestellt.Das Schlüsselwort this bezieht sich auf die aktuelle Klasse, nicht auf die Eigenschaft, in der Sie sich befinden.

Also ja, Sie müssen ein privates Feld deklarieren. Um Verwechslungen zu vermeiden, erstellen Sie Eigenschaften, die der MSDN Naming Guideline folgen (Pascal case für Eigenschaften, camel case für private Felder). Und bitte tun Sie das gleiche für Ihre Methoden, sollte es RevalidateTransformation statt revalidateTransformation sein, wenn Sie die C# -Konvention anstelle von Java folgen.

private string mongoFormId; 
public string MongoFormId 
{ 
    get 
    { 
     return mongoFormId; 
    } 
    set 
    { 
     mongoFormId = value; 
     RevalidateTransformation(); 
    } 
} 
0

Sie können es auf beide Arten tun.

Wenn Sie ein Klasse Level Member-Variable haben wollen dann tut es auf diese Weise -

public class sampleClass 
{ 
    private string _mongoFormId; 

public string mongoFormId { 
      get { return _mongoFormId; } 
      set { 
       _mongoFormId = value; 
       revalidateTransformation(); 
      } 
     } 
} 

Oder tut dies in der Klasse einfach, wenn keine Notwendigkeit für revalidateTransformation() Ausführung Anruf dort

public class sampleClass 
{ 
public string mongoFormId {get; set;} 
} 
+0

stellen Sie sicher, er möchte 'revalidateTransformation();' in Setter aufrufen. Sie können '-' für keine Aufmerksamkeit bekommen – meorfi

0
public string mongoFormId { 
    get { 
     return this.mongoFormId; 
    } 
    set { 
     this.mongoFormId = value; 
     revalidateTransformation(); 
    } 
} 

auf diese Weise haben Sie die Funktion rekursiv auf allen Pfaden Die einzige Möglichkeit, die ich sehe, ist die Verwendung eines privaten Datenelements. Wie andere Jungs erzählen.

Verwandte Themen