Udostępnij za pośrednictwem


Klasy języka C#

Wskazówka

Dopiero zaczynasz programować oprogramowanie? Najpierw zacznij od samouczków Wprowadzenie . Będziesz spotykać klasy, gdy potrzebujesz modelować obiekty ze stanem i zachowaniem.

Czy masz doświadczenie w pracy w innym języku? Klasy języka C# są podobne do klas w języku Java lub C++. Przejrzyj sekcje inicjatorów obiektów i inicjatorów kolekcji, aby znaleźć wzorce specyficzne dla C#, zobacz też Rekordy jako alternatywę ukierunkowaną na dane.

Klasa jest typem referencyjnym, który definiuje strategię dla obiektów. Podczas tworzenia zmiennej typu klasy zmienna przechowuje odwołanie do obiektu na zarządzanym stercie. Zmienna nie przechowuje danych obiektu. Przypisanie zmiennej klasy do innej zmiennej kopiuje odwołanie, więc obie zmienne wskazują ten sam obiekt. Klasy to najbardziej typowy sposób definiowania typów niestandardowych w języku C#. Używaj ich przy potrzebie złożonego zachowania, dziedziczenia lub wspólnej tożsamości między odwołaniami.

Deklarowanie klasy

Zdefiniuj klasę ze class słowem kluczowym, po którym następuje nazwa typu. Opcjonalny modyfikator dostępu kontroluje widoczność. Wartość domyślna to internal:

public class Customer
{
    public string Name { get; set; }

    public Customer(string name) => Name = name;
}

Treść klasy zawiera pola, właściwości, metody i zdarzenia nazywane zbiorczo członkami klasy. Nazwa musi być prawidłową nazwą identyfikatora języka C#.

Utwórz obiekty

Klasa definiuje typ, ale nie jest obiektem. Obiekt ( wystąpienie klasy) tworzy się za pomocą słowa kluczowego new :

var customer = new Customer("Allison");
Console.WriteLine(customer.Name); // Allison

Zmienna customer zawiera odwołanie do obiektu, a nie samego obiektu. Do tego samego obiektu można przypisać wiele zmiennych. Zmiany w jednym odwołaniu są widoczne za pośrednictwem drugiego:

var c1 = new Customer("Grace");
var c2 = c1; // both variables reference the same object

c2.Name = "Hopper";
Console.WriteLine(c1.Name); // Hopper — c1 sees the change made through c2

To zachowanie współużytkowania odwołań to jedno rozróżnienie między klasami i strukturami, w których przypisanie kopiuje dane. Co ważniejsze, klasy obsługują dziedziczenie. Można tworzyć hierarchie, w których typy pochodne ponownie używają i specjalizują zachowanie klasy bazowej. Struktury nie mogą uczestniczyć w hierarchiach dziedziczenia. Aby uzyskać więcej informacji na temat rozróżnienia, zobacz Typy wartości i typy referencyjne.

Konstruktory i inicjalizacja

Podczas tworzenia wystąpienia chcesz zainicjować jego pola i właściwości na wartości użyteczne. Język C# oferuje kilka metod: inicjatory pól, parametry konstruktora, konstruktory podstawowe i wymagane właściwości.

Inicjatory pól ustawiają wartość domyślną bezpośrednio w deklaracji pola:

public class Container
{
    private int _capacity = 10;
}

Inicjatory pól definiują wartości domyślne wewnętrzne . Nie dają rozmówcom żadnego sposobu wybierania wartości początkowej. Aby umożliwić konsumentom klasy dostarczanie wartości, należy użyć jednej z następujących technik.

Parametry konstruktora wymagają od wywołujących podania wartości:

public class Container
{
    private int _capacity;

    public Container(int capacity) => _capacity = capacity;
}

Konstruktory podstawowe (C# 12+) dodają parametry bezpośrednio do deklaracji klasy. Te parametry są dostępne w całej treści klasy:

public class Container(int capacity)
{
    private int _capacity = capacity;
}

Konstruktory podstawowe i inicjatory pól mogą współdziałać ze sobą: inicjator pola _capacity = capacity używa parametru konstruktora podstawowego jako swojej wartości. Ten wzorzec umożliwia przechwytywanie argumentów konstruktora w polach za pomocą jednej zwięzłej deklaracji.

Wymagane właściwości wymuszają, aby wywołujące ustawiały określone właściwości za pomocą inicjatora obiektu:

public class Person
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
}
// var missing = new Person(); // Error: required properties not set
var person = new Person { FirstName = "Grace", LastName = "Hopper" };
Console.WriteLine($"{person.FirstName} {person.LastName}"); // Grace Hopper

Aby uzyskać bardziej szczegółowe informacje na temat wzorców konstruktorów, w tym walidacji parametrów i tworzenia łańcuchów konstruktorów, zobacz Konstruktory.

Klasy statyczne

static Klasa nie może być zainicjowana i zawiera jedynie statyczne elementy członkowskie. Klasy statyczne są używane do organizowania metod pomocniczych, które nie operują na danych instancji.

static class MathHelpers
{
    public static double CircleCircumference(double radius) =>
        2 * Math.PI * radius;
}
double circumference = MathHelpers.CircleCircumference(5.0);
Console.WriteLine($"Circumference: {circumference:F2}"); // Circumference: 31.42

Biblioteka klas platformy .NET zawiera wiele klas statycznych, takich jak Math i Console. Klasa statyczna jest niejawnie zapieczętowana. Nie można go odwzorować ani utworzyć wystąpienia.

Inicjatory obiektów

Inicjatory obiektów umożliwiają ustawianie właściwości podczas tworzenia obiektu bez konieczności pisania konstruktora dla każdej kombinacji wartości:

class ConnectionOptions
{
    public string Host { get; init; } = "localhost";
    public int Port { get; init; } = 80;
    public bool UseSsl { get; init; }
}
var options = new ConnectionOptions
{
    Host = "db.example.com",
    Port = 5432,
    UseSsl = true
};
Console.WriteLine($"{options.Host}:{options.Port} (SSL: {options.UseSsl})");
// db.example.com:5432 (SSL: True)

Inicjatory obiektów działają z dowolną dostępną właściwością, która posiada akcesor set lub init. Łączą się naturalnie z właściwościami required i z konstruktorami, które akceptują niektóre parametry, pozwalając wywołującemu ustawić inne.

Inicjalizatory kolekcji

Kolekcja to typ, który zawiera grupę powiązanych wartości — listy, zestawy, słowniki, tablice i zakresy są typowymi przykładami. Biblioteka klas platformy .NET udostępnia typy kolekcji ogólnego przeznaczenia, takie jak List<T>, Dictionary<TKey,TValue>i HashSet<T>, obok tablic i Span<T>.

Wyrażenia kolekcji (C# 12+) umożliwiają wypełnienie kolekcji bezpośrednio podczas jej tworzenia przy użyciu składni nawiasów kwadratowych:

List<string> languages = ["C#", "F#", "Visual Basic"];

// The spread operator (..) composes collections from existing sequences:
List<string> moreLangs = [.. languages, "Python", "TypeScript"];
Console.WriteLine(string.Join(", ", moreLangs));
// C#, F#, Visual Basic, Python, TypeScript

Wyrażenia kolekcji działają z tablicami, List<T>, Span<T>i dowolnym typem obsługującym inicjowanie kolekcji. Operator spreadu (..) dodaje wszystkie elementy z operandu do nowej kolekcji. Operand nie musi być pełną kolekcją — może to być dowolne wyrażenie, które tworzy sekwencję, taką jak zakres podrzędny, zapytanie LINQ lub filtrowany podzestaw. Aby uzyskać więcej informacji, zobacz Wyrażenia kolekcji (odwołanie w C#).

Dziedziczenie

Klasy obsługują dziedziczenie. Możesz zdefiniować nową klasę, która ponownie używa, rozszerza lub modyfikuje zachowanie istniejącej klasy. Klasa dziedziczona z klasy bazowej jest klasą bazową, a nowa klasa jest klasą pochodną:

var manager = new Manager("Satya", "Engineering");
Console.WriteLine($"{manager.Name} manages {manager.Department}");
// Satya manages Engineering

Klasa może dziedziczyć z jednej klasy bazowej i implementować wiele interfejsów. Klasy pochodne dziedziczą wszystkie elementy członkowskie klasy bazowej z wyjątkiem konstruktorów. Aby uzyskać więcej informacji, zobacz Dziedziczenie i interfejsy.

Kiedy należy używać klas

Użyj klasy, gdy:

  • Typ ma złożone zachowanie lub zarządza stanem modyfikowalnym.
  • Potrzebujesz dziedziczenia, aby utworzyć klasę bazową z pochodnymi specjalizacjami lub utworzyć typ pochodny, który rozszerza istniejącą klasę.
  • Wystąpienia reprezentują tożsamość współdzieloną, a nie tylko pakiet danych (dwa odwołania do tego samego obiektu powinny pozostać zsynchronizowane).
  • Typ jest duży lub długotrwały i korzysta z alokacji sterty i semantyki referencyjnej.

Zobacz także