Konstruktory wystąpień (przewodnik programowania w języku C#)
Zadeklarujesz konstruktor wystąpienia, aby określić kod wykonywany podczas tworzenia nowego wystąpienia typu za pomocą new
wyrażenia . Aby zainicjować klasę statyczną lub zmienne statyczne w klasie niestatycznej, można zdefiniować konstruktor statyczny.
Jak pokazano w poniższym przykładzie, można zadeklarować kilka konstruktorów wystąpień w jednym typie:
class Coords
{
public Coords()
: this(0, 0)
{ }
public Coords(int x, int y)
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
public override string ToString() => $"({X},{Y})";
}
class Example
{
static void Main()
{
var p1 = new Coords();
Console.WriteLine($"Coords #1 at {p1}");
// Output: Coords #1 at (0,0)
var p2 = new Coords(5, 3);
Console.WriteLine($"Coords #2 at {p2}");
// Output: Coords #2 at (5,3)
}
}
W poprzednim przykładzie pierwszy, bez parametrów, konstruktor wywołuje drugi konstruktor z obu argumentów równych 0
. W tym celu użyj słowa kluczowego this
.
Podczas deklarowania konstruktora wystąpienia w klasie pochodnej można wywołać konstruktor klasy bazowej. W tym celu użyj słowa kluczowego base
, jak pokazano w poniższym przykładzie:
abstract class Shape
{
public const double pi = Math.PI;
protected double x, y;
public Shape(double x, double y)
{
this.x = x;
this.y = y;
}
public abstract double Area();
}
class Circle : Shape
{
public Circle(double radius)
: base(radius, 0)
{ }
public override double Area() => pi * x * x;
}
class Cylinder : Circle
{
public Cylinder(double radius, double height)
: base(radius)
{
y = height;
}
public override double Area() => (2 * base.Area()) + (2 * pi * x * y);
}
class Example
{
static void Main()
{
double radius = 2.5;
double height = 3.0;
var ring = new Circle(radius);
Console.WriteLine($"Area of the circle = {ring.Area():F2}");
// Output: Area of the circle = 19.63
var tube = new Cylinder(radius, height);
Console.WriteLine($"Area of the cylinder = {tube.Area():F2}");
// Output: Area of the cylinder = 86.39
}
}
Konstruktory bez parametrów
Jeśli klasa nie ma jawnych konstruktorów wystąpień, język C# udostępnia konstruktor bez parametrów, którego można użyć do utworzenia wystąpienia wystąpienia tej klasy, jak pokazano w poniższym przykładzie:
public class Person
{
public int age;
public string name = "unknown";
}
class Example
{
static void Main()
{
var person = new Person();
Console.WriteLine($"Name: {person.name}, Age: {person.age}");
// Output: Name: unknown, Age: 0
}
}
Ten konstruktor inicjuje pola i właściwości wystąpienia zgodnie z odpowiednimi inicjatorami. Jeśli pole lub właściwość nie ma inicjatora, jego wartość jest ustawiona na wartość domyślną typu pola lub właściwości. Jeśli zadeklarowasz co najmniej jeden konstruktor wystąpienia w klasie, język C# nie udostępnia konstruktora bez parametrów.
Typ struktury zawsze zapewnia konstruktor bez parametrów. Konstruktor bez parametrów jest niejawnym konstruktorem bez parametrów, który generuje wartość domyślną typu lub jawnie zadeklarowany konstruktor bez parametrów. Aby uzyskać więcej informacji, zobacz sekcję Inicjowanie struktury i wartości domyślne w artykule Typy struktury.
Konstruktory podstawowe
Począwszy od języka C# 12, można zadeklarować podstawowy konstruktor w klasach i strukturach. Wszystkie parametry są umieszczane w nawiasach po nazwie typu:
public class NamedItem(string name)
{
public string Name => name;
}
Parametry konstruktora podstawowego znajdują się w zakresie w całej treści typu deklaratywnego. Mogą inicjować właściwości lub pola. Mogą być używane jako zmienne w metodach lub funkcjach lokalnych. Można je przekazać do konstruktora podstawowego.
Podstawowy konstruktor wskazuje, że te parametry są niezbędne dla dowolnego wystąpienia typu. Każdy jawnie napisany konstruktor musi używać this(...)
składni inicjatora do wywoływania konstruktora podstawowego. Zapewnia to, że podstawowe parametry konstruktora są zdecydowanie przypisane przez wszystkie konstruktory. W przypadku dowolnego class
typu, w tym record class
typów, niejawny konstruktor bez parametrów nie jest emitowany, gdy podstawowy konstruktor jest obecny. W przypadku dowolnego struct
typu, w tym record struct
typów, niejawny konstruktor bez parametrów jest zawsze emitowany i zawsze inicjuje wszystkie pola, w tym podstawowe parametry konstruktora, do wzorca 0-bitowego. Jeśli napiszesz jawny konstruktor bez parametrów, musi wywołać konstruktor podstawowy. W takim przypadku można określić inną wartość dla podstawowych parametrów konstruktora. Poniższy kod przedstawia przykłady konstruktorów podstawowych.
// name isn't captured in Widget.
// width, height, and depth are captured as private fields
public class Widget(string name, int width, int height, int depth) : NamedItem(name)
{
public Widget() : this("N/A", 1,1,1) {} // unnamed unit cube
public int WidthInCM => width;
public int HeightInCM => height;
public int DepthInCM => depth;
public int Volume => width * height * depth;
}
Atrybuty można dodać do syntetyzowanej podstawowej metody konstruktora, określając method:
element docelowy atrybutu:
[method: MyAttribute]
public class TaggedWidget(string name)
{
// details elided
}
Jeśli nie określisz method
elementu docelowego, atrybut zostanie umieszczony w klasie, a nie w metodzie.
W class
typach i struct
podstawowe parametry konstruktora są dostępne w dowolnym miejscu w treści typu. Mogą być używane jako pola składowe. Gdy jest używany podstawowy parametr konstruktora, kompilator przechwytuje parametr konstruktora w polu prywatnym z nazwą wygenerowaną przez kompilator. Jeśli podstawowy parametr konstruktora nie jest używany w treści typu, żadne pole prywatne nie jest przechwytywane. Ta reguła uniemożliwia przypadkowe przydzielanie dwóch kopii podstawowego parametru konstruktora przekazanego do konstruktora podstawowego.
Jeśli typ zawiera record
modyfikator, kompilator zamiast tego syntetyzuje właściwość publiczną o takiej samej nazwie jak podstawowy parametr konstruktora. W przypadku record class
typów, jeśli podstawowy parametr konstruktora używa tej samej nazwy co podstawowy konstruktor podstawowy, ta właściwość jest publiczną właściwością typu podstawowego record class
. Nie jest ona duplikowana w typie pochodnym record class
. Te właściwości nie są generowane dla typów innychrecord
niż.
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla