0Pricing
C# Academy · Lekcja

Projektowanie statyczne a instancje

Decyduj, kiedy użycie stanu statycznego jest właściwe.

Projektowanie statyczne a instancje to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 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.

Decyzja projektowa

Wybór między elementem static a instance jest decyzją projektową. Najważniejsze pytanie brzmi: czy działanie zależy od stanu konkretnego obiektu, czy tylko od jego danych wejściowych?

using System;

class Program
{
    // Depends only on inputs -> good static method
    static int Max(int a, int b) => a > b ? a : b;

    static void Main()
    {
        Console.WriteLine(Max(3, 8));
    }
}

Używaj elementów statycznych dla logiki bez stanu

Jeśli metoda nie potrzebuje pól instancji i tylko przekształca dane wejściowe, oznacz ją jako static. Dobrymi przykładami są pomocnicze funkcje matematyczne i formattery.

using System;

static class Convert2
{
    public static double MilesToKm(double miles) => miles * 1.60934;
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Convert2.MilesToKm(10).ToString("0.0") + " km");
    }
}

Używaj instancji dla stanu

Jeśli działanie zależy od danych, które różnią się w poszczególnych obiektach, użyj instance. Każdy obiekt przechowuje własny stan.

using System;

class Counter
{
    private int _count;
    public void Increment() => _count++;
    public int Value => _count;
}

class Program
{
    static void Main()
    {
        var a = new Counter();
        var b = new Counter();
        a.Increment();
        a.Increment();
        b.Increment();
        Console.WriteLine("a=" + a.Value + ", b=" + b.Value);
    }
}

Współdzielony stan jest stanem globalnym

Pole statyczne działa praktycznie jak zmienna globalna. Może powodować trudne do wykrycia błędy, gdy wiele części programu je odczytuje i zapisuje. Jeśli każdy użytkownik potrzebuje własnej kopii, lepiej użyć stanu instancji.

using System;

class BadCart
{
    public static int Items;   // shared by EVERYONE -> usually wrong for a cart
}

class Program
{
    static void Main()
    {
        BadCart.Items++;
        BadCart.Items++;
        Console.WriteLine("All carts share: " + BadCart.Items);
    }
}

Możliwość testowania

Czyste metody statyczne łatwo testować: te same dane wejściowe dają ten sam wynik. Jednak zmienny stan statyczny przenosi się między testami i sprawia, że stają się one podatne na błędy.

using System;

static class Calc
{
    public static int Add(int a, int b) => a + b;   // trivially testable
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Calc.Add(2, 2) == 4 ? "pass" : "fail");
    }
}

Elementy statyczne dla metod fabrykujących

Statyczne metody fabrykujące to przejrzysty sposób tworzenia skonfigurowanych instancji za pomocą opisowej nazwy.

using System;

class Color
{
    public int R, G, B;
    private Color(int r, int g, int b) { R = r; G = g; B = b; }

    public static Color Red() => new Color(255, 0, 0);
    public static Color White() => new Color(255, 255, 255);
}

class Program
{
    static void Main()
    {
        var c = Color.Red();
        Console.WriteLine(c.R + "," + c.G + "," + c.B);
    }
}

Nie używaj elementów statycznych tylko po to, by uniknąć new

Nie oznaczaj wszystkiego jako statyczne tylko po to, by uniknąć tworzenia obiektów. Jeśli typ reprezentuje obiekt mający stan, instancje zapewniają jego odseparowanie i bezpieczeństwo.

using System;

class Player
{
    public string Name;
    public int Health = 100;
    public void TakeDamage(int d) => Health -= d;
}

class Program
{
    static void Main()
    {
        var p1 = new Player { Name = "A" };
        var p2 = new Player { Name = "B" };
        p1.TakeDamage(30);
        Console.WriteLine(p1.Name + ": " + p1.Health + ", " + p2.Name + ": " + p2.Health);
    }
}

Odpowiednie łączenie obu podejść

Wiele klas używa elementów statycznych dla współdzielonych stałych lub liczników, a elementów instancji dla danych konkretnego obiektu. Takie połączenie jest całkowicie zgodne z idiomami języka.

using System;

class Invoice
{
    private static int _seq = 1000;
    public readonly int Number;
    public decimal Amount;

    public Invoice(decimal amount)
    {
        Number = _seq++;
        Amount = amount;
    }
}

class Program
{
    static void Main()
    {
        var i1 = new Invoice(50m);
        var i2 = new Invoice(75m);
        Console.WriteLine(i1.Number + " / " + i2.Number);
    }
}

Kwestia współbieżności

Ze współdzielonego stanu statycznego może jednocześnie korzystać wiele wątków, co grozi wystąpieniem wyścigów. Stan instancji ograniczony do jednego wątku jest domyślnie bezpieczniejszy.

using System;

class SafeCalc
{
    // No shared mutable state -> naturally thread-safe
    public static long Factorial(int n)
    {
        long result = 1;
        for (int i = 2; i <= n; i++) result *= i;
        return result;
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine(SafeCalc.Factorial(5));
    }
}

Prosta zasada

Element statyczny = działanie należące do typu i niekorzystające ze stanu konkretnego obiektu. Instancja = działanie, które odczytuje lub zmienia konkretny obiekt. W razie wątpliwości wybierz instancję dla wszystkiego, co ma stan.

using System;

class Temperature
{
    public double Celsius;                                  // instance state
    public static double ToF(double c) => c * 9 / 5 + 32;   // stateless helper
}

class Program
{
    static void Main()
    {
        var t = new Temperature { Celsius = 30 };
        Console.WriteLine(Temperature.ToF(t.Celsius));
    }
}

Podsumowanie

Dobry projekt oddziela pomocniczą logikę bez stanu (elementy statyczne) od modeli mających stan (instancje), ograniczając współdzielony zmienny stan do świadomie wybranego minimum.

using System;

static class TaxRules
{
    public static decimal Apply(decimal amount, decimal rate) => amount + amount * rate;
}

class Sale
{
    public decimal Subtotal;
    public decimal Total(decimal rate) => TaxRules.Apply(Subtotal, rate);
}

class Program
{
    static void Main()
    {
        var s = new Sale { Subtotal = 100m };
        Console.WriteLine(s.Total(0.2m));
    }
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat projektowania z użyciem elementów statycznych i instancji.

Podsumowanie

Wybierz static dla logiki bez stanu, zależnej wyłącznie od danych wejściowych (metod pomocniczych, fabryk, stałych), a instance dla działania powiązanego ze stanem konkretnego obiektu. Zmienny stan statyczny jest praktycznie globalny, trudniejszy do testowania i grozi błędami współbieżności, dlatego należy ograniczać go do świadomie wybranych przypadków.

using System;

static class Util { public static int Sq(int n) => n * n; }

class Box { public int Size; public int Area() => Util.Sq(Size); }

class Program
{
    static void Main()
    {
        var box = new Box { Size = 4 };
        Console.WriteLine(box.Area());
    }
}

Często zadawane pytania

Czy lekcja „Projektowanie statyczne a instancje” jest bezpłatna?

Tak — pełny tekst „Projektowanie statyczne a instancje” 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 „Projektowanie statyczne a instancje”?

Decyduj, kiedy użycie stanu statycznego jest właściwe. Ć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 4 z 4.

Ile czasu zajmuje lekcja „Projektowanie statyczne a instancje”?

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. Metody i pola statyczne
  2. Klasy statyczne do celów pomocniczych
  3. Stałe i pola readonly
  4. Projektowanie statyczne a instancje
← Powrót do C# Academy