In C #, was unterscheidet ein Feld von einer Eigenschaft und wann sollte ein Feld anstelle einer Eigenschaft verwendet werden?
In C #, was unterscheidet ein Feld von einer Eigenschaft und wann sollte ein Feld anstelle einer Eigenschaft verwendet werden?
Eigenschaften legen Felder offen. Felder sollten (fast immer) für eine Klasse privat gehalten werden und über die Eigenschaften get und set aufgerufen werden. Eigenschaften bieten eine Abstraktionsebene, die es Ihnen ermöglicht, die Felder zu ändern, ohne die externe Zugriffsmöglichkeit der Objekte, die Ihre Klasse verwenden, zu beeinflussen.
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 benötigt werden, sie könnten eine Berechnung für andere Felder durchführen oder anderen Zwecken dienen.
@ GSS weist darauf hin, dass Sie auch andere Logik, wie zum Beispiel die Validierung, beim Zugriff auf eine Eigenschaft verwenden können, eine weitere nützliche Funktion.
Objektorientierte Programmierungsprinzipien sagen, dass das interne Arbeiten einer Klasse von der Außenwelt verborgen sein sollte. Wenn Sie ein Feld verfügbar machen, stellen Sie im Wesentlichen die interne Implementierung der Klasse offen. Daher umschließen wir Felder mit Eigenschaften (oder Methoden im Fall von Java), um uns die Möglichkeit zu geben, die Implementierung zu ändern, ohne Code zu brechen, abhängig von uns. Da wir die Logik in die Eigenschaft einfügen können, können wir auch eine Validierungslogik usw. ausführen, wenn wir sie brauchen. C # 3 hat die möglicherweise verwirrende Vorstellung von Autoproperties. Dies erlaubt uns, einfach die Eigenschaft zu definieren, und der C # 3-Compiler erzeugt 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
}
Ein wichtiger Unterschied besteht darin, dass Schnittstellen Eigenschaften, aber keine Felder haben können. Dies unterstreicht für mich, dass Eigenschaften verwendet werden sollten, um die öffentliche Schnittstelle einer Klasse zu definieren, während Felder dazu bestimmt sind, in den privaten internen Funktionen einer Klasse verwendet zu werden. In der Regel erstelle ich selten öffentliche Felder und auf ähnliche Weise erzeuge ich selten nicht-öffentliche Eigenschaften.
Ich gebe Ihnen ein paar Beispiele für die Verwendung von Eigenschaften, die die Zahnräder drehen könnten:
Mit den Eigenschaften können Sie ein Ereignis auslösen, wenn der Wert der Eigenschaft geändert wird (auch bekannt als PropertyChangedEvent) oder bevor der Wert geändert wird, um die Stornierung zu unterstützen.
Dies ist mit (direktem Zugriff auf) Feldern 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);
}
}
}
Da viele von ihnen mit technischen Vor- und Nachteilen erklärt haben Properties
und Field
, es ist Zeit, in Echtzeit Beispiele zu bekommen.
1. 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 öffentlich für uns. Der Unterschied in der Zugriffsstufe zu ihnen ist, dass wir keinen Wert auf setzen können dataTable.Rows.Count
aber wir können lesen und schreiben dataTable.Columns[i].Caption
. Ist das möglich durch? Field
? Nein!!! Dies kann mit durchgeführt werden Properties
nur.
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
Du hättest vielleicht damit gearbeitet Button
in Visual Studio. Seine Eigenschaften sind in der PropertyGrid
mögen Text
,Name
usw. Wenn wir eine Schaltfläche ziehen und ablegen und auf die Eigenschaften klicken, wird die Klasse automatisch gefunden Button
und Filter Properties
und zeigen das in PropertyGrid
(woher PropertyGrid
wird nicht angezeigt 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;
}
}
Im PropertyGrid
, die Eigenschaften Name
und Text
wird angezeigt, aber nicht SomeProperty
. Warum??? Weil Eigenschaften akzeptieren können Attribute. Es zeigt nicht, wenn [Browsable(false)]
ist falsch.
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 der Bindungsquelle können nur Eigenschaften verwendet werden
Bindequelle hilft uns, die Anzahl der Codezeilen zu verringern. Fields
werden nicht akzeptiert von BindingSource
. Wir sollten ... benutzen Properties
dafür.
5. Debugging-Modus
Überlegen Sie, wir verwenden Field
einen Wert halten. Irgendwann müssen wir debuggen und überprüfen, wo der Wert für dieses Feld null wird. Es wird schwierig sein, zu tun, wo die Anzahl der Codezeilen mehr als 1000 ist. In solchen Situationen können wir verwenden Property
und kann den Debug-Modus einstellen Property
.
public string Name
{
// Can set debug mode inside get or set
get
{
return _name;
}
set
{
_name = value;
}
}
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 haben. Im Allgemeinen sollten Sie Felder verwenden nur für Variablen mit privater oder geschützter Verfügbarkeit. Daten, die Ihre Klasse dem Client-Code zur Verfügung stellt sollte durch Methoden, Eigenschaften zur Verfügung gestellt werden und Indexer. Wenn Sie diese Konstrukte für den indirekten Zugriff auf interne Felder verwenden, können Sie sich vor ungültigen Eingabewerten schützen.
EIN Eigentum ist ein Element, das 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, aber sie sind tatsächlich spezielle aufgerufene Methoden Accessoren. Dies ermöglicht den einfachen Zugriff auf Daten und trägt weiterhin zur Förderung des Sicherheit und Flexibilität der Methoden. Eigenschaften ermöglichen es einer Klasse, eine öffentliche Methode zum Abrufen und Festlegen von Werten verfügbar zu machen, während der Implementierungs- oder Verifizierungscode ausgeblendet wird. Ein Get-Eigenschaft-Accessor wird verwendet, um den Eigenschaftswert zurückzugeben, und ein Set-Accessor wird verwendet, um einen neuen Wert zuzuweisen.
Eigenschaften haben den Hauptvorteil, dass Sie die Art ändern können, in der auf Daten auf einem Objekt zugegriffen wird, ohne die öffentliche Schnittstelle zu unterbrechen. Wenn Sie beispielsweise eine zusätzliche Überprüfung hinzufügen oder ein gespeichertes Feld in ein berechnetes Feld ändern möchten, können Sie dies leicht tun, wenn Sie das Feld zunächst als Eigenschaft angezeigt haben. Wenn Sie ein Feld direkt angezeigt haben, müssten Sie die öffentliche Schnittstelle Ihrer Klasse ändern, um die neue Funktionalität hinzuzufügen. Durch diese Änderung werden vorhandene Clients aufgelöst und müssen neu kompiliert werden, bevor sie die neue Version Ihres Codes verwenden können.
Wenn Sie eine Klassenbibliothek schreiben, die für eine breite Verwendung konzipiert ist (wie das .NET Framework, das von Millionen von Benutzern verwendet wird), kann das ein Problem sein. Wenn Sie jedoch eine Klasse schreiben, die intern in einer kleinen Codebasis verwendet wird (sagen wir <= 50 K-Zeilen), ist das wirklich keine große Sache, weil niemand von Ihren Änderungen beeinträchtigt wird. In diesem Fall kommt es wirklich nur auf persönliche Vorlieben an.
Eigenschaften unterstützen den asymmetrischen Zugriff, d.h. Sie können entweder einen Getter und einen Setter oder nur einen der beiden haben. Ähnlich Eigenschaften unterstützen individuelle Zugänglichkeit für Getter / Setter. Felder sind immer symmetrisch, d. H. Sie können den Wert immer abrufen und festlegen. Ausgenommen davon sind schreibgeschützte Felder, die offensichtlich nach der Initialisierung nicht gesetzt werden können.
Eigenschaften können sehr lange laufen, 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 es bei DateTime.Now der Fall ist, 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 nicht. Eigenschaften unterstützen zusätzliche Logik - dies könnte unter anderem zur Implementierung von Lazy Loading verwendet werden.
Eigenschaften unterstützen eine Abstraktionsebene, indem sie alles einkapseln, was es bedeutet, den Wert zu erhalten / setzen.
Verwenden Sie Eigenschaften in den meisten / allen Fällen, aber versuchen Sie, Nebenwirkungen zu vermeiden.
Im Hintergrund wird eine Eigenschaft in Methoden kompiliert. Also a Name
Eigenschaft wird in kompiliert get_Name()
und set_Name(string value)
. Sie können dies sehen, wenn Sie den kompilierten Code studieren.
Es gibt also einen (sehr) geringen Leistungsaufwand bei der Verwendung. Normalerweise werden Sie immer eine Eigenschaft verwenden, wenn Sie ein Feld nach außen freigeben, und Sie werden es oft intern verwenden, wenn Sie den Wert validieren müssen.