it-swarm.com.de

Was ist der Unterschied zwischen einem Feld und einer Eigenschaft?

Was unterscheidet ein Feld in C # von einer Eigenschaft und wann sollte ein Feld anstelle einer Eigenschaft verwendet werden?

1001
Anonymous

Eigenschaften machen Felder verfügbar. Felder sollten (fast immer) für eine Klasse privat gehalten und über get- und set-Eigenschaften aufgerufen werden. Eigenschaften bieten eine Abstraktionsebene, mit der Sie die Felder ändern können, ohne dass sich dies auf die Art und Weise auswirkt, in der die Elemente, die Ihre Klasse verwenden, auf sie zugreifen.

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty{get;set;} 
}

@Kent weist darauf hin, dass Eigenschaften nicht zum Einkapseln von Feldern erforderlich sind. Sie können eine Berechnung für andere Felder durchführen oder anderen Zwecken dienen.

@GSS weist darauf hin, dass Sie beim Zugriff auf eine Eigenschaft auch andere Logik ausführen können, z. B. die Validierung. Dies ist eine weitere nützliche Funktion.

871
Cory

Objektorientierte Programmierprinzipien besagen, dass die internen Abläufe einer Klasse vor der Außenwelt verborgen sein sollten. Wenn Sie ein Feld verfügbar machen, legen Sie im Wesentlichen die interne Implementierung der Klasse offen. Daher umschließen wir Felder mit Eigenschaften (oder Methoden in Javas Fall), damit wir die Implementierung ändern können, ohne den Code von uns abhängig zu machen. Da wir Logik in die Eigenschaft einfügen können, können wir bei Bedarf auch Validierungslogik usw. ausführen. C # 3 hat den möglicherweise verwirrenden Begriff der Eigenschaf- ten. Dadurch können wir einfach die Eigenschaft definieren und der C # 3-Compiler generiert das private Feld für uns.

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}
240
danswain

Ein wichtiger Unterschied besteht darin, dass Schnittstellen Eigenschaften haben können, aber keine Felder. Dies unterstreicht für mich, dass Eigenschaften verwendet werden sollten, um die öffentliche Schnittstelle einer Klasse zu definieren, während Felder für die private interne Arbeitsweise einer Klasse vorgesehen sind. In der Regel erstelle ich selten öffentliche Felder und ebenso selten nicht öffentliche Eigenschaften.

156
Hans Løken

Ich gebe Ihnen ein paar Beispiele für die Verwendung von Eigenschaften, mit denen sich die Zahnräder drehen können:

  • Lazy Initialization : Wenn Sie eine Eigenschaft eines Objekts haben, das teuer zu laden ist, auf das jedoch nicht allzu oft zugegriffen wird Wenn der Code normal ausgeführt wird, können Sie das Laden über die Eigenschaft verzögern. Auf diese Weise befindet es sich nur dort, aber wenn ein anderes Modul zum ersten Mal versucht, diese Eigenschaft aufzurufen, prüft es, ob das zugrunde liegende Feld null ist. Dies kann die Objektinitialisierung erheblich beschleunigen.
  • Dirty Tracking: Was ich eigentlich aus meiner eigenen Frage hier auf StackOverflow gelernt habe. Wenn ich viele Objekte habe, deren Werte sich während eines Laufs möglicherweise geändert haben, kann ich die Eigenschaft verwenden, um zu verfolgen, ob sie in der Datenbank gespeichert werden müssen oder nicht. Wenn sich nicht eine einzelne Eigenschaft eines Objekts geändert hat, wird das IsDirty-Flag nicht ausgelöst, und daher wird es von der Speicherfunktion übersprungen, wenn entschieden wird, was zur Datenbank zurückgeführt werden muss.
95
Chris

Mit Properties können Sie ein Ereignis auslösen, wenn der Wert der Eigenschaft geändert wird (aka. PropertyChangedEvent) oder bevor der Wert geändert wird, um das Abbrechen zu unterstützen.

Dies ist bei (direktem Zugriff auf) Felder nicht möglich.

public class Person {
 private string _name;

 public event EventHandler NameChanging;     
 public event EventHandler NameChanged;

 public string Name{
  get
  {
     return _name;
  }
  set
  {
     OnNameChanging();
     _name = value;
     OnNameChanged();
  }
 }

 private void OnNameChanging(){
   EventHandler localEvent = NameChanging;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }

 private void OnNameChanged(){
   EventHandler localEvent = NameChanged;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }
}
48
Jehof

Da viele von ihnen die technischen Vor- und Nachteile von Properties und Field erläutert haben, ist es an der Zeit, sich in Echtzeit mit Beispielen zu befassen.

1. Mit Eigenschaften können Sie die schreibgeschützte Zugriffsebene festlegen .

Betrachten Sie den Fall von dataTable.Rows.Count und dataTable.Columns[i].Caption. Sie kommen aus der Klasse DataTable und beide sind für uns öffentlich. Der Unterschied in der Zugriffsebene zu ihnen besteht darin, dass wir den Wert nicht auf dataTable.Rows.Count setzen können, sondern auf dataTable.Columns[i].Caption lesen und schreiben können. Ist das durch Field möglich? Nein!!! Dies ist nur mit Properties möglich.

public class DataTable
{
    public class Rows
    {       
       private string _count;        

       // This Count will be accessable to us but have used only "get" ie, readonly
       public int Count
       {
           get
           {
              return _count;
           }       
       }
    } 

    public class Columns
    {
        private string _caption;        

        // Used both "get" and "set" ie, readable and writable
        public string Caption
        {
           get
           {
              return _caption;
           }
           set
           {
              _caption = value;
           }
       }       
    } 
}

2. Eigenschaften in PropertyGrid

Möglicherweise haben Sie in Visual Studio mit Button gearbeitet. Seine Eigenschaften werden in der PropertyGrid wie Text, Name usw. angezeigt. Wenn wir eine Schaltfläche ziehen und ablegen und auf die Eigenschaften klicken, wird automatisch die Klasse Button und die Filter Properties gefunden und in PropertyGrid angezeigt (wobei PropertyGrid nicht angezeigt wird) Field, obwohl sie öffentlich sind).

public class Button
{
    private string _text;        
    private string _name;
    private string _someProperty;

    public string Text
    {
        get
        {
           return _text;
        }
        set
        {
           _text = value;
        }
   } 

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

   [Browsable(false)]
   public string SomeProperty
   {
        get
        {
           return _someProperty;
        }
        set
        {
           _someProperty= value;
        }
   } 

In PropertyGrid werden die Eigenschaften Name und Text angezeigt, nicht jedoch SomeProperty. Warum??? Weil Eigenschaften Attribute akzeptieren können. Es wird nicht angezeigt, wenn [Browsable(false)] falsch ist.

3. Kann Anweisungen innerhalb von Properties ausführen

public class Rows
{       
    private string _count;        


    public int Count
    {
        get
        {
           return CalculateNoOfRows();
        }  
    } 

    public int CalculateNoOfRows()
    {
         // Calculation here and finally set the value to _count
         return _count;
    }
}

4. In Bindungsquelle können nur Eigenschaften verwendet werden

Binding Source hilft uns, die Anzahl der Codezeilen zu verringern. Fields werden von BindingSource nicht akzeptiert. Wir sollten dafür Properties verwenden.

5. Debugging-Modus

Stellen Sie sich vor, wir verwenden Field, um einen Wert zu speichern. Irgendwann müssen wir debuggen und prüfen, wo der Wert für dieses Feld null wird. Wenn die Anzahl der Codezeilen mehr als 1000 beträgt, ist dies schwierig. In solchen Situationen können wir Property verwenden und den Debug-Modus in Property festlegen.

   public string Name
   {
        // Can set debug mode inside get or set
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   }
43
Sarath Avanavu

UNTERSCHIEDE - VERWENDUNG (wann und warum)

Ein Feld ist eine Variable, die direkt in einer Klasse oder Struktur deklariert wird. Eine Klasse oder Struktur kann Instanzfelder oder statische Felder oder beides enthalten. Im Allgemeinen sollten Sie Felder nur für Variablen verwenden, die über einen privaten oder geschützten Zugriff verfügen . Daten, die Ihre Klasse für Clientcode verfügbar macht , sollten über Methoden, Eigenschaften und Indexer bereitgestellt werden. Indem Sie diese Konstrukte für den indirekten Zugriff auf interne Felder verwenden, können Sie sich vor ungültigen Eingabewerten schützen.

Eine Eigenschaft ist ein Member, der einen flexiblen Mechanismus zum Lesen, Schreiben oder Berechnen des Werts eines privaten Felds bereitstellt. Eigenschaften können verwendet werden, als wären sie öffentliche Datenelemente, es handelt sich jedoch tatsächlich um spezielle Methoden, die als Accessoren bezeichnet werden. Dies ermöglicht einen einfachen Zugriff auf Daten und fördert dennoch die Sicherheit und Flexibilität von Methoden . Mithilfe von Eigenschaften kann eine Klasse eine öffentliche Methode zum Abrufen und Festlegen von Werten bereitstellen, während der Implementierungs- oder Überprüfungscode ausgeblendet wird. Ein get-Eigenschafts-Accessor wird verwendet, um den Eigenschaftswert zurückzugeben, und ein set-Accessor wird verwendet, um einen neuen Wert zuzuweisen.

30
makiSTB

Eigenschaften haben den Hauptvorteil, dass Sie den Zugriff auf Daten eines Objekts ändern können, ohne die öffentliche Schnittstelle zu beschädigen. Wenn Sie beispielsweise eine zusätzliche Validierung hinzufügen oder ein gespeichertes Feld in ein berechnetes Feld ändern müssen, können Sie dies problemlos tun, wenn Sie das Feld ursprünglich als Eigenschaft verfügbar gemacht haben. Wenn Sie ein Feld nur direkt verfügbar gemacht hätten, müssten Sie die öffentliche Schnittstelle Ihrer Klasse ändern, um die neue Funktionalität hinzuzufügen. Diese Änderung würde bestehende Clients beschädigen und eine Neukompilierung erforderlich machen, bevor sie die neue Version Ihres Codes verwenden können.

Wenn Sie eine Klassenbibliothek schreiben, die für den breiten Verbrauch ausgelegt ist (wie das .NET Framework, das von Millionen von Menschen verwendet wird), kann dies ein Problem sein. Wenn Sie jedoch eine Klasse schreiben, die intern in einer kleinen Codebasis (z. B. <= 50 KByte) verwendet wird, ist dies keine große Sache, da Ihre Änderungen niemanden nachteilig beeinflussen würden. In diesem Fall kommt es wirklich nur auf die persönlichen Vorlieben an.

12

Im Hintergrund wird eine Eigenschaft in Methoden kompiliert. So wird eine Name -Eigenschaft in get_Name() und set_Name(string value) kompiliert. Sie können dies sehen, wenn Sie den kompilierten Code studieren. Daher entsteht bei deren Verwendung ein (sehr) geringer Performance-Aufwand. Normalerweise verwenden Sie eine Eigenschaft immer, wenn Sie ein Feld nach außen freigeben, und Sie verwenden es häufig intern, wenn Sie den Wert überprüfen müssen.

10
Rune Grimstad

Eigenschaften unterstützen asymmetrischen Zugriff, d. H. Sie können entweder einen Getter und einen Setter oder nur einen der beiden haben. Ebenso unterstützen Eigenschaften die individuelle Zugänglichkeit für Getter/Setter. Felder sind immer symmetrisch, d. H. Sie können den Wert immer sowohl abrufen als auch festlegen. Eine Ausnahme bilden schreibgeschützte Felder, die nach der Initialisierung offensichtlich nicht mehr gesetzt werden können.

Eigenschaften können sehr lange ausgeführt werden, Nebenwirkungen haben und sogar Ausnahmen auslösen. Felder sind schnell, ohne Nebenwirkungen und werden niemals Ausnahmen auslösen. Aufgrund von Nebenwirkungen kann eine Eigenschaft für jeden Aufruf einen anderen Wert zurückgeben (wie dies für DateTime.Now der Fall sein kann, d. H. DateTime.Now ist nicht immer gleich DateTime.Now). Felder geben immer den gleichen Wert zurück.

Felder können für out/ref-Parameter verwendet werden, Eigenschaften möglicherweise nicht. Eigenschaften unterstützen zusätzliche Logik - dies kann unter anderem zum Implementieren von verzögertem Laden verwendet werden.

Eigenschaften unterstützen eine Abstraktionsebene, indem sie alles einkapseln, was es bedeutet, den Wert abzurufen/festzulegen.

Verwenden Sie in den meisten Fällen Eigenschaften, vermeiden Sie jedoch Nebenwirkungen.

10
Brian Rasmussen

Wenn Ihre private Variable (Feld) für Objekte Ihrer Klasse aus anderen Klassen zugänglich sein soll, müssen Sie Eigenschaften für diese Variablen erstellen.

zum Beispiel, wenn ich Variablen mit den Namen "id" und "name" habe, die privat sind, es aber Situationen geben kann, in denen diese Variable für Lese-/Schreibvorgänge außerhalb der Klasse benötigt wird. In dieser Situation kann Eigenschaft mir helfen, diese Variable abhängig von dem für die Eigenschaft definierten get/set zum Lesen/Schreiben zu bringen. Eine Eigenschaft kann schreibgeschützt/schreibgeschützt/schreibgeschützt sein.

hier ist die Demo

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}
7
Petryanu

Die zweite Frage hier: "Wann soll ein Feld anstelle einer Eigenschaft verwendet werden?" Wird nur kurz in diese andere Antwort und irgendwie auch diese angesprochen, aber nicht wirklich viel Detail.

Im Allgemeinen sprechen alle anderen Antworten für gutes Design: Belichten Sie lieber Eigenschaften als Felder. Sie werden wahrscheinlich nicht regelmäßig sagen : "Wow, stellen Sie sich vor, wie viel schlimmer es wäre, wenn ich dieses Feld anstelle eines Grundstücks gemacht hätte." Es ist so viel seltener, an eine Situation zu denken, in der man sagen würde: "Wow, Gott sei Dank, ich habe hier ein Feld anstelle eines Grundstücks verwendet."

Aber es gibt einen Vorteil, den Felder gegenüber Eigenschaften haben, und das ist ihre Fähigkeit, als "ref"/"out" -Parameter verwendet zu werden. Angenommen, Sie haben eine Methode mit der folgenden Signatur:

public void TransformPoint(ref double x, ref double y);

angenommen, Sie möchten diese Methode verwenden, um ein Array zu transformieren, das wie folgt erstellt wurde:

System.Windows.Point[] points = new Point[1000000];
Initialize(points);

Hier ist meiner Meinung nach der schnellste Weg, da X und Y Eigenschaften sind:

for (int i = 0; i < points.Length; i++)
{
    double x = points[i].X;
    double y = points[i].Y;
    TransformPoint(ref x, ref y);
    points[i].X = x;
    points[i].Y = y;
}

Und das wird ziemlich gut! Wenn Sie keine Messungen haben, die das Gegenteil beweisen, gibt es keinen Grund, einen Gestank zu werfen. Aber ich glaube, es ist technisch nicht garantiert, dass es so schnell ist:

internal struct MyPoint
{
    internal double X;
    internal double Y;
}

// ...

MyPoint[] points = new MyPoint[1000000];
Initialize(points);

// ...

for (int i = 0; i < points.Length; i++)
{
    TransformPoint(ref points[i].X, ref points[i].Y);
}

Bei einigen Messungen selbst benötigt die Version mit Feldern ungefähr 61% der Zeit als die Version mit Eigenschaften (.NET 4.6, Windows 7, x64, Freigabemodus, kein Debugger angehängt). Je teurer die Methode TransformPoint wird, desto geringer wird der Unterschied. Um dies selbst zu wiederholen, führen Sie die erste auskommentierte und nicht auskommentierte Zeile aus.

Selbst wenn es keine Leistungsvorteile für die oben genannten gibt, gibt es andere Stellen, an denen die Verwendung von ref- und out-Parametern von Vorteil sein kann, z. B. beim Aufrufen von Interlocked oder Volatile Methodenfamilie. Hinweis: Falls dies für Sie neu ist, ist Volatile im Grunde eine Möglichkeit, dasselbe Verhalten wie mit dem Schlüsselwort volatile zu erreichen. Als solches, wie volatile, löst es nicht auf magische Weise alle Sicherheitslücken, wie der Name vermuten lässt.

Ich möchte auf keinen Fall den Eindruck erwecken, als würde ich dafür plädieren, dass Sie "oh, ich sollte anfangen, Felder anstelle von Eigenschaften freizulegen". Der Punkt ist, dass, wenn Sie diese Member regelmäßig in Aufrufen verwenden müssen, die "ref" - oder "out" -Parameter annehmen, insbesondere in einem einfachen Wertetyp, der wahrscheinlich nie eines der Mehrwertelemente von Eigenschaften benötigt. Ein Argument kann vorgebracht werden.

6
Joe Amenta

Diese Seite auf MSDN enthält einen Vergleich und Tipps, die Sie verwenden sollten, wenn:

https://msdn.Microsoft.com/en-us/library/9d65as2e (v = vs.90) .aspx

4
shivesh suman

Technisch glaube ich nicht, dass es einen Unterschied gibt, weil Eigenschaften nur Wrapper um vom Benutzer erstellte oder vom Compiler automatisch erstellte Felder sind. Der Zweck von Eigenschaften besteht darin, die Kapselung zu erzwingen und eine einfache methodenähnliche Funktion anzubieten. Es ist nur eine schlechte Praxis, Felder als öffentlich zu deklarieren, aber es gibt keine Probleme.

4

Wenn Sie Thread-Primitive verwenden, müssen Sie Felder verwenden. Eigenschaften können Ihren Thread-Code beschädigen. Abgesehen davon ist das, was Cory sagte, richtig.

(Dies sollte eigentlich ein Kommentar sein, aber ich kann keinen Kommentar posten, bitte entschuldigen Sie, wenn er nicht als Beitrag geeignet ist.).

Ich habe einmal an einem Ort gearbeitet, an dem die empfohlene Vorgehensweise darin bestand, öffentliche Felder anstelle von Eigenschaften zu verwenden, wenn die entsprechende Eigenschaft def nur auf ein Feld zugegriffen hätte, wie in:

get { return _afield; }
set { _afield = value; }

Ihre Argumentation war, dass das öffentliche Feld später bei Bedarf in eine Immobilie umgewandelt werden könnte. Es kam mir damals etwas seltsam vor. Nach diesen Beiträgen zu urteilen, scheinen auch hier nicht viele zuzustimmen. Was könnten Sie gesagt haben, um zu versuchen, Dinge zu ändern?

Bearbeiten: Ich sollte hinzufügen, dass die gesamte Codebasis an diesem Ort zur gleichen Zeit kompiliert wurde, so dass sie gedacht haben könnten, dass das Ändern der öffentlichen Schnittstelle von Klassen (durch Ändern eines öffentlichen Felds in eine Eigenschaft) kein Problem war.

4
Moe Sisko

Felder sind gewöhnliche Mitgliedsvariablen oder Mitgliedsinstanzen einer Klasse. Eigenschaften sind ein Abstraktion zum Abrufen und Festlegen ihrer Werte. Eigenschaften werden auch als Accessoren bezeichnet, da sie die Möglichkeit bieten, ein Feld zu ändern und abzurufen, wenn Sie ein Feld in der Klasse als privat verfügbar machen. Im Allgemeinen sollten Sie Ihre Mitgliedsvariablen als privat deklarieren und dann Eigenschaften für sie deklarieren oder definieren.

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }
4
Vasim Shaikh

Mithilfe von Eigenschaften können Sie beim Festlegen von Werten auch Logik verwenden.

Sie können also sagen, dass Sie nur dann einen Wert für ein ganzzahliges Feld festlegen möchten, wenn der Wert größer als x ist. Andernfalls wird eine Ausnahme ausgelöst.

Wirklich nützliche Funktion.

4
GurdeepS

Traditionell werden private Felder über Getter- und Setter-Methoden gesetzt. Um den Code zu reduzieren, können Sie stattdessen mithilfe von Eigenschaften Felder festlegen.

3
Chris Paine

Aus Wikipedia - Objektorientierte Programmierung :

Objektorientierte Programmierung (OOP) ist ein Programmierparadigma, das auf dem Konzept von "Objekten" basiert. Hierbei handelt es sich um Datenstrukturen, die Daten in Form von Feldern enthalten , oft als Attribute bezeichnet; und Code in Form von Prozeduren, die oft als Methoden bezeichnet werden. (Hervorhebung hinzugefügt)

Eigenschaften sind eigentlich Teil des Verhaltens eines Objekts, sollen jedoch den Verbrauchern des Objekts die Illusion/Abstraktion vermitteln, mit den Daten des Objekts zu arbeiten.

3
Zev Spitz

Eigenschaften kapseln Felder ein, sodass Sie den einzustellenden oder abzurufenden Wert weiter verarbeiten können. Es ist in der Regel zu viel des Guten, Eigenschaften zu verwenden, wenn Sie keine Vor- oder Nachbearbeitung für den Feldwert ausführen.

3
Erik Burger

wenn Sie eine Klasse haben, die "Auto" ist. Die Eigenschaften sind Farbe, Form ..

Wobei as-Felder Variablen sind, die im Bereich einer Klasse definiert sind.

3
user406580

Felder sind die Variablen in Klassen. Felder sind die Daten, die Sie mithilfe von Zugriffsmodifikatoren kapseln können.

Eigenschaften ähneln Fields, da sie Zustände und die mit einem Objekt verknüpften Daten definieren.

Im Gegensatz zu einem Feld hat eine Eigenschaft eine spezielle Syntax, die steuert, wie eine Person die Daten liest und schreibt. Diese werden als get- und set-Operatoren bezeichnet. Die eingestellte Logik kann häufig zur Validierung verwendet werden.

3
Neil Meyer

IMO, Properties sind nur die "SetXXX ()" - "GetXXX ()" - Funktionen/Methoden/Schnittstellen-Paare, die wir zuvor verwendet haben, aber sie sind prägnanter und eleganter.

3
Junchao Xu

Mein Design eines Feldes ist, dass ein Feld nur von seinem Elternteil geändert werden muss, daher die Klasse. Das Ergebnis ist, dass die Variable privat wird. Um dann das Recht zu geben, die Klassen/Methoden außerhalb des Systems zu lesen, gehe ich nur mit Get durch das Eigenschaftensystem. Das Feld wird dann von der Eigenschaft abgerufen und ist schreibgeschützt! Wenn Sie es ändern möchten, müssen Sie Methoden durchgehen (zum Beispiel den Konstruktor), und ich finde, dass wir dank dieser Art, Sie zu schützen, eine bessere Kontrolle über unseren Code haben, weil wir "flanschen". Man könnte sehr wohl immer alles öffentlich machen, also jeder mögliche Fall, die Vorstellung von Variablen/Methoden/Klassen etc ... ist meiner Meinung nach nur eine Hilfe bei der Entwicklung, Pflege des Codes. Wenn zum Beispiel eine Person einen Code mit öffentlichen Feldern wieder aufnimmt, kann sie alles und damit Dinge tun, die in Bezug auf das Ziel, die Logik, warum der Code geschrieben wurde, "unlogisch" sind. Das ist meine Sichtweise.

Wenn ich ein klassisches Modell Private Field/Public Readonly-Eigenschaften verwende, sollte ich für 10 Private Fields 10 Publics-Eigenschaften schreiben! Der Code kann sehr viel schneller sein. Ich entdecke den privaten Setter und verwende jetzt nur öffentliche Eigenschaften mit einem privaten Setter. Der Setter erstellt im Hintergrund ein privates Feld.

Deshalb war mein alter klassischer Programmierstil:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

Mein neuer Programmierstil:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}
3
Tony Pinot

Grundlegender und allgemeiner Unterschied ist:

Felder

  • ALWAYS Zugriff sowohl auf get als auch auf set gewähren
  • KANN NICHT Nebenwirkungen verursachen (Ausnahmen auslösen, Methoden aufrufen, Felder ändern, außer dem, der gerade abgerufen/gesetzt wird, usw.)

Eigenschaften

  • NICHT IMMER Zugriff auf get und set gewähren
  • KANN Nebenwirkungen verursachen
2
Ted Mucuzany

Denken Sie darüber nach: Sie haben einen Raum und eine Tür, um diesen Raum zu betreten. Wenn Sie überprüfen möchten, wie wer hereinkommt, und Ihr Zimmer sichern möchten, sollten Sie Objekte verwenden, da diese sonst keine Tür darstellen und alle ohne Vorschriften problemlos hereinkommen

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

Die Leute kommen ziemlich leicht zu SectionOne, es gab keine Überprüfung

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

Jetzt hast du die Person überprüft und weißt, ob sie etwas Böses bei sich hat

2
user8080469

In den allermeisten Fällen handelt es sich um einen Eigenschaftsnamen, auf den Sie zugreifen, und nicht um einen Variablennamen (). Der Grund dafür ist, dass er als gut angesehen wird Üben Sie in .NET und insbesondere in C #, um alle Daten einer Klasse zu schützen, unabhängig davon, ob es sich um eine Instanzvariable oder eine statische Variable (Klassenvariable) handelt, da sie einer Klasse zugeordnet sind.

Schützen Sie alle Variablen mit den entsprechenden Eigenschaften, mit denen Sie festlegen und abrufen Accessoren können, und führen Sie bei Bedarf Überprüfungen durch manipulieren diese Daten.

In anderen Fällen wie Math-Klasse (System-Namespace) sind jedoch einige statische Eigenschaften in die Klasse integriert. Eine davon ist die mathematische Konstante PI

z.B. Math.PI

und da PI ein genau definiertes Datenelement ist, müssen wir nicht mehrere Kopien von PI haben, es wird immer der gleiche Wert sein. Daher werden statische Variablen manchmal verwendet, um Daten für Objekte einer Klasse freizugeben. Sie werden jedoch auch häufig für konstante Informationen verwendet, wenn Sie nur eine Kopie eines Datenelements benötigen.

2
Nermien Barakat

Eigenschaften werden verwendet, um das Feld verfügbar zu machen. Sie verwenden Accessoren (set, get), über die die Werte der privaten Felder gelesen, geschrieben oder manipuliert werden können.

Eigenschaften benennen die Speicherorte nicht. Stattdessen verfügen sie über Accessoren, die ihre Werte lesen, schreiben oder berechnen.

Mithilfe von Eigenschaften können wir die Validierung für den Datentyp festlegen, der für ein Feld festgelegt ist.

Zum Beispiel haben wir ein privates ganzzahliges Alter, bei dem wir positive Werte zulassen sollten, da das Alter nicht negativ sein kann.

Wir können dies auf zwei Arten tun, indem wir Getter und Setter und Property verwenden.

 Using Getter and Setter

    // field
    private int _age;

    // setter
    public void set(int age){
      if (age <=0)
       throw new Exception();

      this._age = age;
    }

    // getter
    public int get (){
      return this._age;
    }

 Now using property we can do the same thing. In the value is a key Word

    private int _age;

    public int Age{
    get{
        return this._age;
    }

    set{
       if (value <= 0)
         throw new Exception()
       }
    }

Automatisch implementierte Eigenschaft Wenn keine Logik zum Abrufen und Festlegen von Accessoren vorhanden ist, können Sie die automatisch implementierte Eigenschaft verwenden.

Wenn u Diese automatisch implementierte Eigenschaftskompilierung erstellt ein privates, anonymes Feld, auf das nur über get- und set-Accessoren zugegriffen werden kann.

public int Age{get;set;}

Abstrakte Eigenschaften Eine abstrakte Klasse kann eine abstrakte Eigenschaft haben, die in der abgeleiteten Klasse implementiert werden sollte

public abstract class Person
   {
      public abstract string Name
      {
         get;
         set;
      }
      public abstract int Age
      {
         get;
         set;
      }
   }

// overriden something like this
// Declare a Name property of type string:
  public override string Name
  {
     get
     {
        return name;
     }
     set
     {
        name = value;
     }
  }

Wir können privat eine Eigenschaft setzen. In dieser können wir privat die Eigenschaft auto setzen (setzen mit in der Klasse).

public int MyProperty
{
    get; private set;
}

Mit diesem Code können Sie dasselbe erreichen. In diesem Eigenschaftssatz ist keine Funktion verfügbar, da der Wert direkt auf Feld gesetzt werden muss.

private int myProperty;
public int MyProperty
{
    get { return myProperty; }
}
2

Eigenschaften sind eine spezielle Art von Klassenmitgliedern. In Eigenschaften verwenden wir eine vordefinierte Set- oder Get-Methode. Sie verwenden Zugriffsmethoden, mit denen wir die Werte der privaten Felder lesen, schreiben oder ändern können.

Nehmen wir zum Beispiel eine Klasse namens Employee mit privaten Feldern für Name, Alter und Employee_Id. Wir können nicht von außerhalb der Klasse auf diese Felder zugreifen, aber wir können über Eigenschaften auf diese privaten Felder zugreifen.

Warum verwenden wir Eigenschaften?

Das Klassenfeld öffentlich zu machen und offenzulegen ist riskant, da Sie nicht kontrollieren können, was zugewiesen und zurückgegeben wird.

Um dies anhand eines Beispiels klar zu verstehen, nehmen wir eine Schülerklasse mit ID, PassMark und Name. Nun in diesem Beispiel ein Problem mit dem öffentlichen Bereich

  • ID sollte nicht -ve sein.
  • Name kann nicht auf null gesetzt werden
  • Das Bestandenzeichen sollte nur gelesen werden.
  • Wenn der Name des Schülers fehlt, sollte kein Name zurückgegeben werden.

Um dieses Problem zu beheben, verwenden wir die Methode Get and Set.

// A simple example
public class student
{
    public int ID;
    public int PassMark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

Nun nehmen wir ein Beispiel für die Methode get und set

public class student
{
    private int _ID;
    private int _PassMark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for PassMark property
    public int Getpassmark()
    {
        return this._PassMark;
    }
}
2
ahmed alkhatib

Obwohl Felder und Eigenschaften ähnlich aussehen, handelt es sich um zwei völlig unterschiedliche Sprachelemente.

  1. Felder sind der einzige Mechanismus zum Speichern von Daten auf Klassenebene. Felder sind konzeptionell Variablen im Klassenbereich. Wenn Sie einige Daten in Instanzen Ihrer Klassen (Objekte) speichern möchten, müssen Sie Felder verwenden. Es gibt keine andere Wahl. In den Eigenschaften können keine Daten gespeichert werden, obwohl dies anscheinend möglich ist. Siehe unten.

  2. Eigenschaften hingegen speichern niemals Daten. Dies sind nur die Methodenpaare (get und set), die syntaktisch ähnlich wie Felder aufgerufen werden können und auf die in den meisten Fällen zugegriffen wird (zum Lesen oder Schreiben) ) Felder, die einige Verwirrung stiften. Da es sich bei Eigenschaftsmethoden jedoch (mit einigen Einschränkungen wie bei festen Prototypen) um reguläre C # -Methoden handelt, können sie alle regulären Methoden ausführen. Dies bedeutet, dass sie 1000 Codezeilen haben, Ausnahmen auslösen, andere Methoden aufrufen, sogar virtuell, abstrakt oder überschrieben sein können. Das Besondere an Eigenschaften ist, dass der C # -Compiler einige zusätzliche Metadaten in Assemblys speichert, mit denen nach bestimmten Eigenschaften gesucht werden kann - häufig verwendete Funktion.

Die Methode zum Abrufen und Festlegen von Eigenschaften weist die folgenden Prototypen auf.

PROPERTY_TYPE get();

void set(PROPERTY_TYPE value);

Dies bedeutet, dass Eigenschaften 'emuliert' werden können, indem ein Feld und zwei entsprechende Methoden definiert werden.

class PropertyEmulation
{
    private string MSomeValue;

    public string GetSomeValue()
    {
        return(MSomeValue);
    }

    public void SetSomeValue(string value)
    {
        MSomeValue=value;
    }
}

Eine solche Eigenschaftsemulation ist typisch für Programmiersprachen, die keine Eigenschaften unterstützen - wie Standard-C++. In C # sollten Sie immer Eigenschaften bevorzugen, um auf Ihre Felder zugreifen zu können.

Da nur die Felder Daten speichern können, bedeutet dies, dass mehr Felder in der Klasse enthalten sind und mehr Speicherobjekte dieser Klasse belegt werden. Andererseits vergrößert das Hinzufügen neuer Eigenschaften zu einer Klasse Objekte dieser Klasse nicht. Hier ist das Beispiel.

class OneHundredFields
{
        public int Field1;
        public int Field2;
        ...
        public int Field100;
}

OneHundredFields Instance=new OneHundredFields() // Variable 'Instance' consumes 100*sizeof(int) bytes of memory.

class OneHundredProperties
{
    public int Property1
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }

    public int Property2
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }

    ...

    public int Property100
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }
}

OneHundredProperties Instance=new OneHundredProperties() // !!!!! Variable 'Instance' consumes 0 bytes of memory. (In fact a some bytes are consumed becasue every object contais some auxiliarity data, but size doesn't depend on number of properties).

Obwohl Eigenschaftsmethoden alles können, dienen sie in den meisten Fällen dazu, auf die Felder von Objekten zuzugreifen. Wenn Sie ein Feld für andere Klassen zugänglich machen möchten, haben Sie zwei Möglichkeiten.

  1. Felder öffentlich machen - nicht ratsam.
  2. Eigenschaften verwenden.

Hier ist eine Klasse, die öffentliche Felder verwendet.

class Name
{
    public string FullName;
    public int YearOfBirth;
    public int Age;
}

Name name=new Name();

name.FullName="Tim Anderson";
name.YearOfBirth=1979;
name.Age=40;

Obwohl der Code vollkommen gültig ist, weist er aus gestalterischer Sicht mehrere Nachteile auf. Da Felder sowohl gelesen als auch geschrieben werden können, können Sie den Benutzer nicht daran hindern, in Felder zu schreiben. Sie können das Schlüsselwort readonly anwenden. Auf diese Weise müssen Sie jedoch schreibgeschützte Felder nur im Konstruktor initialisieren. Darüber hinaus hindert Sie nichts daran, ungültige Werte in Ihren Feldern zu speichern.

name.FullName=null;
name.YearOfBirth=2200;
name.Age=-140;

Der Code ist gültig, alle Zuweisungen werden ausgeführt, obwohl sie unlogisch sind. Age hat einen negativen Wert, YearOfBirth ist weit in der Zukunft und entspricht nicht dem Alter und FullName ist null. Mit Feldern können Sie Benutzer von class Name nicht daran hindern, solche Fehler zu machen.

Hier ist ein Code mit Eigenschaften, der diese Probleme behebt.

class Name
{
    private string MFullName="";
    private int MYearOfBirth;

    public string FullName
    {
        get
        {
            return(MFullName);
        }
        set
        {
            if (value==null)
            {
                throw(new InvalidOperationException("Error !"));
            }

            MFullName=value;
        }
    }

    public int YearOfBirth
    {
        get
        {
            return(MYearOfBirth);
        }
        set
        {
            if (MYearOfBirth<1900 || MYearOfBirth>DateTime.Now.Year)
            {
                throw(new InvalidOperationException("Error !"));
            }

            MYearOfBirth=value;
        }
    }

    public int Age
    {
        get
        {
            return(DateTime.Now.Year-MYearOfBirth);
        }
    }

    public string FullNameInUppercase
    {
        get
        {
            return(MFullName.ToUpper());
        }
    }
}

Die aktualisierte Version der Klasse bietet die folgenden Vorteile.

  1. FullName und YearOfBirth werden auf ungültige Werte überprüft.
  2. Age ist nicht beschreibbar. Es wird aus YearOfBirth und dem aktuellen Jahr berechnet.
  3. Eine neue Eigenschaft FullNameInUppercase konvertiert FullName in UPPER CASE. Dies ist ein wenig konstruiertes Beispiel für die Verwendung von Eigenschaften, bei dem Eigenschaften üblicherweise verwendet werden, um Feldwerte in einem Format darzustellen, das für den Benutzer besser geeignet ist - beispielsweise unter Verwendung des aktuellen Gebietsschemas für eine bestimmte Zahl des Formats DateTime.

Daneben können Eigenschaften als virtuell oder überschrieben definiert werden - einfach weil es sich um reguläre .NET-Methoden handelt. Für solche Eigenschaftsmethoden gelten die gleichen Regeln wie für reguläre Methoden.

C # unterstützt auch Indexer, bei denen es sich um Eigenschaften handelt, die in Eigenschaftsmethoden einen Indexparameter aufweisen. Hier ist das Beispiel.

class MyList
{
    private string[]                 MBuffer;

    public MyList()
    {
        MBuffer=new string[100];
    }

    public string this[int Index]
    {
        get
        {
            return(MBuffer[Index]);
        }
        set
        {
            MBuffer[Index]=value;
        }
    }
}

MyList   List=new MyList();

List[10]="ABC";
Console.WriteLine(List[10]);

Seit C # 3.0 können Sie automatische Eigenschaften definieren. Hier ist das Beispiel.

class AutoProps
{
    public int Value1
    {
        get;
        set;
    }

    public int Value2
    {
        get;
        set;
    }
}

Obwohl class AutoProps nur Eigenschaften enthält (oder so aussieht), kann es 2 Werte speichern und die Größe von Objekten dieser Klasse entspricht sizeof(Value1)+sizeof(Value2) = 4 + 4 = 8 Bytes.

Der Grund dafür ist einfach. Wenn Sie eine automatische Eigenschaft definieren, generiert der C # -Compiler automatisch Code, der ein ausgeblendetes Feld und eine Eigenschaft enthält, deren Eigenschaftenmethoden auf dieses ausgeblendete Feld zugreifen. Hier produziert der Code-Compiler.

Hier ist ein Code, der von ILSpy aus einer kompilierten Assembly generiert wird. Klasse enthält generierte ausgeblendete Felder und Eigenschaften.

internal class AutoProps
{
    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private int <Value1>k__BackingField;

    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private int <Value2>k__BackingField;

    public int Value1
    {
        [CompilerGenerated]
        get
        {
            return <Value1>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            <Value1>k__BackingField = value;
        }
    }

    public int Value2
    {
        [CompilerGenerated]
        get
        {
            return <Value2>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            <Value2>k__BackingField = value;
        }
    }
}

Wie Sie sehen, verwendet der Compiler die Felder weiterhin zum Speichern der Werte, da nur mithilfe von Feldern Werte in Objekten gespeichert werden können.

Wie Sie sehen, stellen Eigenschaften und Felder eine ähnliche Verwendungssyntax dar. Auch wenn Sie automatische Eigenschaften oder Ereignisse verwenden, handelt es sich um verborgene Felder Vom Compiler generiert, in dem die realen Daten gespeichert sind.

Wenn Sie einen Feldwert für die Außenwelt zugänglich machen müssen (Benutzer Ihrer Klasse), verwenden Sie keine öffentlichen oder geschützten Felder. Felder sollten immer als privat markiert werden. Mithilfe von Eigenschaften können Sie Wertüberprüfungen, Formatierungen, Konvertierungen usw. durchführen und Ihren Code im Allgemeinen sicherer, lesbarer und erweiterbarer machen, damit er in Zukunft geändert werden kann.

1
Timmy_A

Zusätzliche Informationen: Standardmäßig sind Zugriffsmethoden zum Abrufen und Festlegen so zugänglich wie die Eigenschaft selbst. Sie können den Zugriff auf den Accessor individuell steuern/einschränken (zum Abrufen und Festlegen), indem Sie restriktivere Zugriffsmodifikatoren auf ihn anwenden.

Beispiel:

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

Hier wird immer noch öffentlich auf get zugegriffen (da die Eigenschaft öffentlich ist), aber set ist geschützt (ein eingeschränkterer Zugriffsspezifizierer).

1
Django