0Pricing
C# Academy · Lekcja

Łańcuchowanie konstruktorów za pomocą this

Ponownie wykorzystuj inicjalizację w różnych konstruktorach.

Łańcuchowanie konstruktorów za pomocą this to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Po co łączyć konstruktory

Gdy kilka konstruktorów współdzieli logikę konfiguracji, można je łączyć, tak aby jeden wywoływał drugi. Pozwala to uniknąć duplikowania kodu i umieścić inicjalizację w jednym miejscu.

using System;

class Box
{
    public int Width;
    public int Height;

    public Box(int width, int height)
    {
        Width = width;
        Height = height;
    }

    public Box() : this(1, 1) { }
}

class Program
{
    static void Main()
    {
        var def = new Box();
        Console.WriteLine(def.Width + "x" + def.Height);
    }
}

Składnia : this(...)

Łączenie konstruktorów wykorzystuje zapis : this(args) umieszczony po sygnaturze konstruktora. Wskazany konstruktor jest uruchamiany najpierw, a dopiero potem wykonywane jest ciało bieżącego konstruktora.

using System;

class Person
{
    public string Name;
    public int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
        Console.WriteLine("Full constructor ran");
    }

    public Person(string name) : this(name, 0)
    {
        Console.WriteLine("Name-only constructor ran");
    }
}

class Program
{
    static void Main()
    {
        var p = new Person("Sam");
        Console.WriteLine(p.Name + ", " + p.Age);
    }
}

Kolejność wykonywania

Połączony konstruktor jest wykonywany przed ciałem konstruktora, który go wywołuje. Dzięki temu podstawowa konfiguracja zawsze odbywa się wcześniej.

using System;

class Step
{
    public Step(int n)
    {
        Console.WriteLine("Init with " + n);
    }

    public Step() : this(0)
    {
        Console.WriteLine("Then default body");
    }
}

class Program
{
    static void Main()
    {
        var s = new Step();
    }
}

Jedno źródło prawdy

Skieruj wszystkie konstruktory do jednego „głównego” konstruktora, który zawiera właściwą logikę. Pozostałe dostarczają tylko wartości domyślne i przekazują wykonanie do niego.

using System;

class Connection
{
    public string Host;
    public int Port;

    public Connection(string host, int port)
    {
        Host = host;
        Port = port;
    }

    public Connection(string host) : this(host, 8080) { }
    public Connection() : this("localhost", 8080) { }
}

class Program
{
    static void Main()
    {
        var c = new Connection("example.com");
        Console.WriteLine(c.Host + ":" + c.Port);
    }
}

Łączenie z wartościami domyślnymi

Łączenie konstruktorów to przejrzysty sposób wyrażania warstwowych wartości domyślnych: każdy krótszy konstruktor uzupełnia jedną dodatkową wartość domyślną i przekazuje wykonanie dalej.

using System;

class Coffee
{
    public string Size;
    public bool Milk;
    public int Sugar;

    public Coffee(string size, bool milk, int sugar)
    {
        Size = size;
        Milk = milk;
        Sugar = sugar;
    }

    public Coffee(string size, bool milk) : this(size, milk, 0) { }
    public Coffee(string size) : this(size, false) { }
}

class Program
{
    static void Main()
    {
        var c = new Coffee("large");
        Console.WriteLine(c.Size + ", milk=" + c.Milk + ", sugar=" + c.Sugar);
    }
}

Walidacja w konstruktorze docelowym

Ponieważ każdy konstruktor przechodzi przez główny konstruktor, umieszczona w nim walidacja chroni wszystkie ścieżki tworzenia obiektu.

using System;

class Rect
{
    public int W;
    public int H;

    public Rect(int w, int h)
    {
        if (w <= 0 || h <= 0)
            throw new ArgumentException("Dimensions must be positive");
        W = w;
        H = h;
    }

    public Rect(int side) : this(side, side) { }
}

class Program
{
    static void Main()
    {
        var square = new Rect(5);
        Console.WriteLine(square.W + "x" + square.H);
    }
}

Łączenie a domyślne wartości parametrów

Domyślne wartości parametrów mogą zastąpić wiele przeciążeń, ale łączenie konstruktorów jest przejrzystsze, gdy każdy konstruktor wymaga nieco innej logiki w swoim ciele.

using System;

class Logger
{
    public string Prefix;
    public bool Verbose;

    public Logger(string prefix, bool verbose)
    {
        Prefix = prefix;
        Verbose = verbose;
    }

    public Logger(string prefix) : this(prefix, false)
    {
        Console.WriteLine("Created quiet logger");
    }
}

class Program
{
    static void Main()
    {
        var log = new Logger("APP");
        Console.WriteLine(log.Prefix + " verbose=" + log.Verbose);
    }
}

Puste ciała są częste

Konstruktor łączący często ma puste ciało { }, ponieważ cała praca jest wykonywana w konstruktorze docelowym.

using System;

class Vector
{
    public double X, Y, Z;

    public Vector(double x, double y, double z)
    {
        X = x; Y = y; Z = z;
    }

    public Vector(double v) : this(v, v, v) { }
}

class Program
{
    static void Main()
    {
        var v = new Vector(2);
        Console.WriteLine(v.X + "," + v.Y + "," + v.Z);
    }
}

Unikanie cykli

Konstruktory nie mogą tworzyć pętli wywołań (A wywołuje B, a B wywołuje A). Kompilator odrzuca cykliczne łańcuchy : this(...).

using System;

class Safe
{
    public int A, B;

    public Safe(int a, int b)
    {
        A = a;
        B = b;
    }

    public Safe(int a) : this(a, 0) { }   // chains one direction only
}

class Program
{
    static void Main()
    {
        var s = new Safe(7);
        Console.WriteLine(s.A + ", " + s.B);
    }
}

Łączenie z this.field

Można łączyć konstruktory i nadal używać this. w ciele do wykonania dodatkowej konfiguracji po powrocie z konstruktora docelowego.

using System;

class Account
{
    public string Owner;
    public decimal Balance;
    public bool Active;

    public Account(string owner, decimal balance)
    {
        this.Owner = owner;
        this.Balance = balance;
    }

    public Account(string owner) : this(owner, 0m)
    {
        this.Active = true;
    }
}

class Program
{
    static void Main()
    {
        var a = new Account("Rin");
        Console.WriteLine(a.Owner + " active=" + a.Active);
    }
}

Połączenie wszystkiego

Łączenie konstruktorów pozwala zachować zasadę DRY w klasie: jeden konstruktor przeprowadza walidację i przypisuje wartości, a pozostałe zapewniają wygodne skróty.

using System;

class Pizza
{
    public string Size;
    public int Toppings;

    public Pizza(string size, int toppings)
    {
        if (toppings < 0) throw new ArgumentException("toppings");
        Size = size;
        Toppings = toppings;
    }

    public Pizza(string size) : this(size, 0) { }
    public Pizza() : this("medium") { }
}

class Program
{
    static void Main()
    {
        var p = new Pizza();
        Console.WriteLine(p.Size + " with " + p.Toppings + " toppings");
    }
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat łączenia konstruktorów.

Podsumowanie

Łączenie konstruktorów wykorzystuje : this(args) do wywołania innego konstruktora w tej samej klasie. Konstruktor docelowy jest wykonywany jako pierwszy, a następnie wykonywane jest ciało bieżącego konstruktora. Skieruj każdy konstruktor do jednego głównego konstruktora, aby scentralizować walidację i uniknąć zduplikowanej konfiguracji. Cykliczne łańcuchy są niedozwolone.

using System;

class Demo
{
    public int X, Y;
    public Demo(int x, int y) { X = x; Y = y; }
    public Demo(int both) : this(both, both) { }
}

class Program
{
    static void Main()
    {
        var d = new Demo(4);
        Console.WriteLine(d.X + "," + d.Y);
    }
}

Często zadawane pytania

Czy lekcja „Łańcuchowanie konstruktorów za pomocą this” jest bezpłatna?

Tak — pełny tekst „Łańcuchowanie konstruktorów za pomocą this” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Łańcuchowanie konstruktorów za pomocą this”?

Ponownie wykorzystuj inicjalizację w różnych konstruktorach. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Łańcuchowanie konstruktorów za pomocą this”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Definiowanie konstruktorów
  2. Łańcuchowanie konstruktorów za pomocą this
  3. Inicjalizatory obiektów i kolekcji
  4. Konstruktory statyczne
← Powrót do C# Academy