Verwenden von Eigenschaften (C#-Programmierhandbuch)
Eigenschaften kombinieren Aspekte der Felder und der Methoden. Für Benutzer*innen eines Objekts scheint eine Eigenschaft ein Feld zu sein; der Zugriff auf die Eigenschaft erfordert dieselbe Syntax. Für den Implementierer einer Klasse, besteht eine Eigenschaft aus einem oder zwei Codeblöcken, die einen get-Accessor und/oder einen set-Accessor darstellen. Der Codeblock für die get
-Zugriffsmethode wird ausgeführt, wenn die Eigenschaft gelesen wird; der Codeblock für die set
-Zugriffsmethode wird ausgeführt, wenn der Eigenschaft ein Wert zugewiesen wird. Eine Eigenschaft ohne einen set
-Accessor ist schreibgeschützt. Eine Eigenschaft ohne einen get
-Accessor ist lesegeschützt. Eine Eigenschaft, die beide Accessoren umfasst, ermöglicht Lese-/ Schreibzugriff. Sie können eine init
-Zugriffsmethode anstelle einer set
-Zugriffsmethode verwenden, um die Eigenschaft als schreibgeschützt zu kennzeichnen.
Im Gegensatz zu Feldern, werden Eigenschaften nicht als Variablen klassifiziert. Aus diesem Grund können Sie Eigenschaften nicht als ref oder out-Parameter übergeben.
Eigenschaften sind vielseitig verwendbar: Sie können Daten überprüfen, bevor sie eine Änderung zulassen. Sie können Daten in einer Klasse transparent verfügbar machen, in denen die Daten von einer anderen Quelle abgerufen werden, z.B. einer Datenbank. Sie können eine Aktion ausführen, wenn Daten geändert werden, z.B. ein Ereignis auslösen, oder den Wert anderer Felder verändern.
Eigenschaften werden im Klassenblock deklariert, indem die Zugriffsebene des Felds angegeben wird, gefolgt vom Typ der Eigenschaft, gefolgt vom Namen der Eigenschaft und gefolgt von einem Codeblock, der einen get
-Accessor und/oder einen set
Accessor deklariert. Zum Beispiel:
public class Date
{
private int _month = 7; // Backing store
public int Month
{
get => _month;
set
{
if ((value > 0) && (value < 13))
{
_month = value;
}
}
}
}
In diesem Beispiel wird Month
als Eigenschaft so deklariert, dass der set
-Accessor dafür sorgen kann, dass der Month
-Wert zwischen 1 und 12 festgelegt wird. Die Month
-Eigenschaft verwendet ein privates Feld, um den tatsächlichen Wert nachzuverfolgen. Der tatsächliche Speicherort der Daten einer Eigenschaft wird häufig als „Sicherungsspeicher“ der Eigenschaft bezeichnet. Es ist üblich, dass Eigenschaften private Felder als Sicherungsspeicher verwenden. Das Feld wird als privat gekennzeichnet um sicherzustellen, dass es nur durch Aufrufen der Eigenschaft geändert werden kann. Weitere Informationen zu öffentlichen und privaten Zugriffsbeschränkungen finden Sie unter Zugriffsmodifizierer.
Automatisch implementierte Eigenschaften stellen eine vereinfachte Syntax für einfache Eigenschaftendeklarationen bereit. Weitere Informationen finden Sie unter Automatisch implementierte Eigenschaften.
Die get-Zugriffsmethode
Der Text des get
Accessors ähnelt dem einer Methode. Er muss einen Wert des Eigenschaftentyps zurückgeben. Die Ausführung des get
Accessors entspricht dem Lesen des Wert des Felds. Wenn Sie z. B. die private Variable von der get
-Zugriffsmethode zurückgeben und Optimierungen aktiviert sind, wird der Aufruf an die get
-Zugriffsmethode vom Compiler eingebettet, damit kein zusätzlicher Aufwand an Methodenaufrufen entsteht. Allerdings kann eine virtuelle get
-Zugriffsmethode nicht eingebettet werden, da der Compiler zum Zeitpunkt der Kompilierung nicht weiß, welche Methode zur Laufzeit tatsächlich aufgerufen wird. Das folgende Beispiel veranschaulicht eine get
-Zugriffsmethode, die den Wert eines privaten Felds (_name
) zurückgibt:
class Employee
{
private string _name; // the name field
public string Name => _name; // the Name property
}
Wenn Sie auf die Eigenschaft, außer als Ziel einer Zuweisung, verweisen, wird der get
-Accessor aufgerufen, um den Wert der Eigenschaft zu lesen. Zum Beispiel:
var employee= new Employee();
//...
System.Console.Write(employee.Name); // the get accessor is invoked here
Die get
-Zugriffsmethode muss mit einer return- oder einer throw-Anweisung enden, und die Steuerung darf nicht über den Text der Zugriffsmethode hinausgehen.
Warnung
Es ist kein guter Programmierstil, den Zustand des Objekts mithilfe der get
-Zugriffsmethode zu verändern.
Der get
-Accessor kann verwendet werden, um den Wert des Felds zurückzugeben, oder um den Wert des Felds zu berechnen und zurückgeben. Zum Beispiel:
class Manager
{
private string _name;
public string Name => _name != null ? _name : "NA";
}
Im obigen Codesegment wird der Wert NA
zurückgegeben, wenn Sie der Name
-Eigenschaft keinen Wert zuweisen.
Die set-Zugriffsmethode
Der set
-Accessor ähnelt einer Methode, deren Rückgabetyp void ist. Er verwendet einen impliziten Parameter mit dem Namen value
, dessen Typ der Typ der Eigenschaft ist. Im folgenden Beispiel wird ein set
-Accessor der Name
-Eigenschaft hinzugefügt.
class Student
{
private string _name; // the name field
public string Name // the Name property
{
get => _name;
set => _name = value;
}
}
Wenn Sie der Eigenschaft einen Wert zuweisen, wird der set
-Accessor mit einem Argument aufgerufen, das den neuen Wert bereitstellt. Zum Beispiel:
var student = new Student();
student.Name = "Joe"; // the set accessor is invoked here
System.Console.Write(student.Name); // the get accessor is invoked here
Das Verwenden des impliziten Parameternamens, value
, für die Deklaration einer lokalen Variablen in einer set
-Zugriffsmethode führt zu einem Fehler.
Die init-Zugriffsmethode
Der Code zum Erstellen einer init
-Zugriffsmethode ist derselbe wie der Code zum Erstellen einer set
-Zugriffsmethode, mit der Ausnahme, dass Sie das Schlüsselwort init
anstelle von set
verwenden. Der Unterschied besteht darin, dass die init
-Zugriffsmethode nur im Konstruktor oder mithilfe eines Objektinitialisierers verwendet werden kann.
Hinweise
Eigenschaften können als public
, private
, protected
, internal
, protected internal
oder private protected
gekennzeichnet werden. Diese Zugriffsmodifizierer definieren, wie Benutzer der Klasse auf die Eigenschaft zugreifen können. Die get
- und set
-Accessoren für die gleiche Eigenschaft haben möglicherweise verschiedene Zugriffsmodifizierer. Z.B. kann get
möglicherweise public
sein, um den schreibgeschützten Zugriff von außerhalb des Typs zu ermöglichen, und set
kann möglicherweise private
oder protected
sein. Weitere Informationen finden Sie unter Zugriffsmodifizierer.
Eine Eigenschaft kann als statische Eigenschaft deklariert werden, mithilfe des static
-Schlüsselworts. Statische Eigenschaften stehen Aufrufern jederzeit zur Verfügung, auch wenn keine Instanz der Klasse vorhanden ist. Weitere Informationen finden Sie unter Statische Klassen und statische Klassenmember.
Ein Ereignis kann mithilfe des virtual-Schlüsselworts als virtuelles Ereignis gekennzeichnet werden. Virtuelle Eigenschaften ermöglichen es abgeleiteten Klassen, das Ereignisverhalten mit dem override-Schlüsselwort zu überschreiben. Weitere Informationen zu diesen Optionen finden Sie unter Vererbung.
Eine Eigenschaft, die eine virtuelle Eigenschaft überschreibt, kann auch versiegelt (sealed) werden, um anzugeben, dass sie für abgeleitete Klassen nicht mehr virtuell ist. Schließlich kann eine Eigenschaft als abstract(abstrakt) deklariert werden. Abstrakte Eigenschaften definieren keine Implementierung in der Klasse, sodass für abgeleitete Klassen eine eigene Implementierung geschrieben werden muss. Weitere Informationen zu abstrakten Klassen finden Sie unter Abstrakte und versiegelte Klassen und Klassenmember.
Hinweis
Das Verwenden eines virtual(virtuell)-, abstract(abstrakt)- oder override(außer Kraft setzen)- Modifizierers für einen Accessor einer statischen Eigenschaft ist ein Fehler.
Beispiele
Dieses Beispiel zeigt,Instanz-, statische- und schreibgeschützte Eigenschaften. Dieser Parameter akzeptiert den Namen des Mitarbeiters auf der Tastatur, Inkremente NumberOfEmployees
durch 1, und zeigt den Mitarbeiternamen und die Nummer an.
public class Employee
{
public static int NumberOfEmployees;
private static int _counter;
private string _name;
// A read-write instance property:
public string Name
{
get => _name;
set => _name = value;
}
// A read-only static property:
public static int Counter => _counter;
// A Constructor:
public Employee() => _counter = ++NumberOfEmployees; // Calculate the employee's number:
}
Beispiel für eine ausgeblendete Eigenschaft
In diesem Beispiel wird veranschaulicht, wie auf eine Eigenschaft in einer Basisklasse zugegriffen werden kann, die von einer anderen Eigenschaft ausgeblendet ist, die in einer abgeleiteten Klasse den gleichen Namen hat:
public class Employee
{
private string _name;
public string Name
{
get => _name;
set => _name = value;
}
}
public class Manager : Employee
{
private string _name;
// Notice the use of the new modifier:
public new string Name
{
get => _name;
set => _name = value + ", Manager";
}
}
class TestHiding
{
public static void Test()
{
Manager m1 = new Manager();
// Derived class property.
m1.Name = "John";
// Base class property.
((Employee)m1).Name = "Mary";
System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);
System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
}
}
/* Output:
Name in the derived class is: John, Manager
Name in the base class is: Mary
*/
Die folgenden Punkte im vorherigen Beispiel sind wichtig:
- Die Eigenschaft
Name
in der abgeleiteten Klasse blendet die EigenschaftName
in der Basisklasse aus. In solch einem Fall wird dernew
-Modifizierer in der Deklaration der Eigenschaft in der abgeleiteten Klasse verwendet:public new string Name
- Die Umwandlung
(Employee)
wird für den Zugriff auf die ausgeblendete Eigenschaft in der Basisklasse verwendet:((Employee)m1).Name = "Mary";
Weitere Informationen zum Ausblenden von Mitgliedern finden Sie unter new-Modifizierer.
Beispiel für Überschreibungseigenschaft
In diesem Beispiel implementieren zwei Klassen Cube
und Square
eine abstrakte Klasse Shape
, und überschreiben die abstrakte Area
-Eigenschaft. Beachten Sie die Verwendung des überschreiben-Modifizierers in den Eigenschaften. Das Programm akzeptiert die Seite als Eingabe und berechnet die Bereiche für das Quadrat und den Cube. Das Programm akzeptiert auch den Bereich als Eingabe und berechnet die entsprechende Seite für das Quadrat und den Cube.
abstract class Shape
{
public abstract double Area
{
get;
set;
}
}
class Square : Shape
{
public double side;
//constructor
public Square(double s) => side = s;
public override double Area
{
get => side * side;
set => side = System.Math.Sqrt(value);
}
}
class Cube : Shape
{
public double side;
//constructor
public Cube(double s) => side = s;
public override double Area
{
get => 6 * side * side;
set => side = System.Math.Sqrt(value / 6);
}
}
class TestShapes
{
static void Main()
{
// Input the side:
System.Console.Write("Enter the side: ");
double side = double.Parse(System.Console.ReadLine());
// Compute the areas:
Square s = new Square(side);
Cube c = new Cube(side);
// Display the results:
System.Console.WriteLine("Area of the square = {0:F2}", s.Area);
System.Console.WriteLine("Area of the cube = {0:F2}", c.Area);
System.Console.WriteLine();
// Input the area:
System.Console.Write("Enter the area: ");
double area = double.Parse(System.Console.ReadLine());
// Compute the sides:
s.Area = area;
c.Area = area;
// Display the results:
System.Console.WriteLine("Side of the square = {0:F2}", s.side);
System.Console.WriteLine("Side of the cube = {0:F2}", c.side);
}
}
/* Example Output:
Enter the side: 4
Area of the square = 16.00
Area of the cube = 96.00
Enter the area: 24
Side of the square = 4.90
Side of the cube = 2.00
*/
Siehe auch
Feedback
Feedback senden und anzeigen für