11 Stimmen

C# 3.0 :Automatische Eigenschaften - wie lautet der Name der privaten Variable, die vom Compiler erstellt wird

Ich habe mir die neuen Funktionen von .NET 3.5 angesehen und festgestellt, dass wir in C# 3.0 Folgendes verwenden können

public class Person 
{    
 public string FirstName  { get; set; }
 public string LastName  { get; set; }
}

anstelle von

private string name;

public string Name
{
  get { return name; }
  set { name = value; }
}

Wenn ich die automatischen Eigenschaften verwende, was wird der Name der privaten Variable für Name sein? die Tutorials im Internet sagen, dass der Compiler automatisch eine private Variable erstellt. wie kann ich also die private Variable verwenden/auf sie zugreifen, wenn ich sie in einer Methode in dieser Klasse verwenden möchte?

3 Stimmen

Beachten Sie, dass dies ein Feature von C# 3.0 ist, nicht von .NET 3.5 - Sie können es auch verwenden, wenn Sie .NET 2.0 von einem C# 3.0-Compiler aus anvisieren.

0 Stimmen

21voto

Lasse V. Karlsen Punkte 364542

Umgeschrieben, um mehr Klarheit zu schaffen

Das Feld wird zwar generiert, aber es ist für Ihren Code nicht als normales Feld sichtbar.

Das ist die typische automatische Eigenschaft:

public string FirstName  { get; set; }

was, wenn wir uns die kompilierte Assembly ansehen, dieses Backing-Store-Feld erzeugt:

[CompilerGenerated]
private string <FirstName>k__BackingField;

Beachten Sie die Zeichen < und >, die Sie nicht in Ihren eigenen Feldnamen verwenden können. Sie können auch nicht auf dieses Feld zugreifen, da es für den Compiler nicht "existiert", wenn er sich Ihren Code ansieht.

Die eigentliche Frage, die sich mir stellt, ist por qué Sie auf dieses Feld zugreifen möchten. Mit anderen Worten, warum brauchen Sie Zugriff auf das Feld, und was tut es für Ihren Code, dass der Zugriff auf die Eigenschaft nicht tun?

Wenn Sie den Schreibzugriff von außen auf das Feld verhindern wollen, ist das leicht möglich, indem Sie die Setter-Methode privat machen, etwa so:

public string FirstName  { get; private set; }

Da das Feld tatsächlich in der Assembly vorhanden ist, bedeutet dies, dass es sich nicht um JITter-Magie, sondern um Compiler-Magie handelt, so dass Sie Reflection verwenden können, um das Feld zu finden und darauf zuzugreifen.

Aber noch einmal: Warum sollten Sie das wollen?

Nehmen wir einmal an, dass es wirklich einen legitimen Grund dafür gibt, dass Sie das Feld anstelle der Eigenschaft verwenden wollen. Ich kann mir einen vorstellen, obwohl ich es wahrscheinlich anders machen würde, und das wäre, dass Sie den Feldnamen als Out- oder Ref-Parameter an eine Methode übergeben wollen, wie hier:

public void AdjustName(ref String name)
{
    name = Capitalize(name);
}

Sie können keine Eigenschaften als out/ref-Parameter übergeben, daher wird dieser Code nicht funktionieren:

AdjustName(ref string FirstName);

In diesem Fall müssen Sie auf die "alte" Methode der Eigenschaftsdefinition zurückgreifen und das Feld "Backing Store" manuell hinzufügen, etwa so:

private string firstName;
public string FirstName
{
    get { return firstName; }
    set { firstName = value; }
}

Damit können Sie diese Methode aufrufen:

AdjustName(ref string firstName); // note the field, not the property

Allerdings würde ich diese Methode wahrscheinlich so ändern, dass der neue Wert zurückgegeben wird, anstatt eine referenzierte Variable direkt anzupassen.

0 Stimmen

Ich möchte den Wert der Eigenschaft in einer Methode verwenden, die einige mathematische Berechnungen durchführt

0 Stimmen

Warum also nicht einfach die Immobilie selbst nutzen?

0 Stimmen

Das Einzige, was get tut, ist, diesen spezifischen Wert zurückzugeben ;).

5voto

Achim Punkte 14879

Wie bereits gesagt: Sie können nicht auf die automatisch generierte Variable zugreifen (ohne schlechte Tricks). Aber ich gehe davon aus, dass Sie diese Frage stellen, weil Sie nur einen Getter haben wollen, aber trotzdem automatische Eigenschaften verwenden wollen ... richtig? In diesem Fall können Sie diese verwenden:

public string FirstName  { get; private set; }

Jetzt haben Sie einen privaten Setter und einen öffentlichen Getter.

1voto

John Saunders Punkte 159011

Wenn Sie automatische Eigenschaften verwenden, können Sie nicht auf das private Feld zugreifen. Es ist nicht nur privat, es ist auch anonym.

0 Stimmen

Das stimmt. Wenn Sie, aus welchen Gründen auch immer, meinen, Sie bräuchten den Zugriff auf das private Mitglied (abgesehen davon, dass Sie "aus Neugier" wissen wollen, wie es heißt), dann implementieren Sie die Eigenschaft nicht auf diese Weise, sondern definieren Sie Ihr eigenes privates Mitglied. Wie "in den alten Zeiten" ;-)

0voto

Saajid Ismail Punkte 7481

Wie kann ich also die private Variable verwenden/auf sie zugreifen, wenn ich sie in einer Methode in dieser Klasse verwenden möchte?

In Ihrem Quellcode müssen und dürfen Sie nur mit dem Property Accessor arbeiten person.LastName o LastName wenn Sie Code innerhalb der Personenklasse schreiben.

Der Compiler erstellt automatisch eine private Mitgliedsvariable oder ein Backing-Feld, das jedoch in der CIL Code. Er existiert nirgendwo in Ihrem Quellcode.

0 Stimmen

@Shyju: Ich glaube, Sie gehen von der falschen Annahme aus, dass Visual Studio automatisch ein privates Feld generiert, das Sie verwenden können. Die automatische Generierung erfolgt durch den Compiler und ist nur im CIL-Code vorhanden.

0 Stimmen

Wenn Sie wirklich und wahrhaftig auf das private Feld zugreifen müssen, können Sie Reflexion verwenden. Aber ich bin mir ziemlich sicher, dass dies nicht das ist, was Sie wollen,

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X