Konstruktory instancí (průvodce programováním v C#)
Deklarujete konstruktor instance, který určí kód, který se spustí při vytvoření nové instance typu s výrazemnew
. Chcete-li inicializovat statickou třídu nebo statické proměnné v nestatické třídě, můžete definovat statický konstruktor.
Jak ukazuje následující příklad, můžete deklarovat několik konstruktorů instance v jednom typu:
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)
}
}
V předchozím příkladu první, bez parametrů, konstruktor volá druhý konstruktor s oběma argumenty rovná 0
. K tomu použijte this
klíčové slovo.
Když deklarujete konstruktor instance v odvozené třídě, můžete volat konstruktor základní třídy. Uděláte to tak, že použijete base
klíčové slovo, jak ukazuje následující příklad:
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ů
Pokud třída nemá žádné explicitní konstruktory instancí, jazyk C# poskytuje konstruktor bez parametrů, který můžete použít k vytvoření instance této třídy, jak ukazuje následující příklad:
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
}
}
Tento konstruktor inicializuje pole a vlastnosti instance podle odpovídajících inicializátorů. Pokud pole nebo vlastnost nemá žádný inicializátor, jeho hodnota je nastavena na výchozí hodnotu typu pole nebo vlastnosti. Pokud deklarujete alespoň jeden konstruktor instance ve třídě, jazyk C# neposkytuje konstruktor bez parametrů.
Typ struktury vždy poskytuje konstruktor bez parametrů. Konstruktor bez parametrů je implicitní konstruktor bez parametrů, který vytváří výchozí hodnotu typu nebo explicitně deklarovaný konstruktor bez parametrů. Další informace naleznete v části Inicializace struktury a výchozí hodnoty v článku Typy struktur.
Primární konstruktory
Počínaje jazykem C# 12 můžete deklarovat primární konstruktor ve třídách a strukturách. Všechny parametry umístíte do závorek za názvem typu:
public class NamedItem(string name)
{
public string Name => name;
}
Parametry primárního konstruktoru jsou v oboru v celém těle deklarujícího typu. Mohou inicializovat vlastnosti nebo pole. Lze je použít jako proměnné v metodách nebo místních funkcích. Mohou být předány do základního konstruktoru.
Primární konstruktor označuje, že tyto parametry jsou nezbytné pro jakoukoli instanci typu. Jakýkoli explicitně napsaný konstruktor musí použít this(...)
syntaxi inicializátoru k vyvolání primárního konstruktoru. Tím zajistíte, že parametry primárního konstruktoru budou rozhodně přiřazeny všemi konstruktory. U jakéhokoli class
typu, včetně record class
typů, se implicitní konstruktor bez parametrů nevygeneruje, pokud je k dispozici primární konstruktor. U libovolného struct
typu, včetně record struct
typů, je implicitní konstruktor bez parametrů vždy generován a vždy inicializuje všechna pole, včetně parametrů primárního konstruktoru, na 0bitový vzor. Pokud napíšete explicitní konstruktor bez parametrů, musí vyvolat primární konstruktor. V takovém případě můžete pro parametry primárního konstruktoru zadat jinou hodnotu. Následující kód ukazuje příklady primárních konstruktorů.
// 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;
}
Do syntetizované primární metody konstruktoru můžete přidat atributy zadáním method:
cíle atributu:
[method: MyAttribute]
public class TaggedWidget(string name)
{
// details elided
}
Pokud cílovou hodnotu nezadáte method
, atribut se umístí do třídy místo metody.
Parametry class
primárního konstruktoru jsou struct
k dispozici kdekoli v těle typu. Parametr lze implementovat jako zachycené privátní pole. Pokud jsou jedinými odkazy na parametr inicializátory a volání konstruktoru, tento parametr se nezachytí v privátním poli. Používá se v jiných členech typu, protože kompilátor zachytává parametr v privátním poli.
Pokud typ obsahuje record
modifikátor, kompilátor místo toho syntetizuje veřejnou vlastnost se stejným názvem jako primární konstruktor parametr. U record class
typů platí, že pokud parametr primárního konstruktoru používá stejný název jako základní primární konstruktor, je tato vlastnost veřejnou vlastností základního record class
typu. Není duplicitní v odvozeném record class
typu. Tyto vlastnosti nejsou generovány pro jinérecord
typy.