0Pricing
C# Academy · Lekcja

Typy wartości a typy referencyjne

Zobacz, jak każdy z nich jest przechowywany i kopiowany.

Typy wartości a typy referencyjne to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 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.

Dwie rodziny typów

Typy w języku C# dzielą się na typy wartościowe (int, double, bool, struktury) i typy referencyjne (klasy, ciągi znaków, tablice). Różnią się sposobem przechowywania i kopiowania.

using System;

class Program
{
    static void Main()
    {
        int valueType = 5;          // value type
        int[] referenceType = { 1, 2, 3 };  // reference type
        Console.WriteLine(valueType + ", length " + referenceType.Length);
    }
}

Typy wartościowe przechowują dane

Zmienna typu wartościowego zawiera swoje dane bezpośrednio. Zwykle znajdują się one na stosie lub bezpośrednio wewnątrz obiektu, który je zawiera.

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        double b = 3.14;
        bool c = true;
        Console.WriteLine(a + ", " + b + ", " + c);
    }
}

Typy referencyjne przechowują adres

Zmienna typu referencyjnego przechowuje referencję (adres) do danych znajdujących się na stercie. Zmienna i obiekt są od siebie oddzielne.

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box b = new Box();   // b refers to a heap object
        b.Value = 42;
        Console.WriteLine(b.Value);
    }
}

Semantyka kopiowania: typy wartościowe

Przypisanie typu wartościowego kopiuje dane. Zmiana kopii nigdy nie wpływa na oryginał.

using System;

class Program
{
    static void Main()
    {
        int a = 1;
        int b = a;   // copy
        b = 99;
        Console.WriteLine("a=" + a + ", b=" + b);
    }
}

Semantyka kopiowania: typy referencyjne

Przypisanie typu referencyjnego kopiuje odwołanie, a nie obiekt. Obie zmienne wskazują wtedy na ten sam obiekt.

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box a = new Box { Value = 1 };
        Box b = a;   // same object
        b.Value = 99;
        Console.WriteLine("a.Value=" + a.Value + ", b.Value=" + b.Value);
    }
}

Struktury są typami wartości

Zdefiniowany przez Państwa struct jest typem wartości, więc podczas przypisania jest kopiowany tak samo jak int.

using System;

struct Point { public int X, Y; }

class Program
{
    static void Main()
    {
        Point p1 = new Point { X = 1, Y = 2 };
        Point p2 = p1;   // full copy
        p2.X = 99;
        Console.WriteLine("p1.X=" + p1.X + ", p2.X=" + p2.X);
    }
}

Przekazywanie do metod

Domyślnie typy wartości są przekazywane przez kopię, a typy referencyjne przekazują kopię odwołania. Metoda może więc zmienić obiekt klasy widoczny dla kodu wywołującego, ale nie zwykłą wartość typu int.

using System;

class Counter { public int N; }

class Program
{
    static void BumpInt(int x) { x++; }
    static void BumpObj(Counter c) { c.N++; }

    static void Main()
    {
        int i = 0;
        BumpInt(i);
        var c = new Counter();
        BumpObj(c);
        Console.WriteLine("i=" + i + ", c.N=" + c.N);
    }
}

null i typy referencyjne

Tylko typy referencyjne mogą mieć wartość null (oznaczającą brak obiektu). Typy wartości zawsze przechowują wartość, chyba że zadeklarowano je jako dopuszczające wartość null za pomocą ?.

using System;

class Program
{
    static void Main()
    {
        string text = null;        // reference type can be null
        int? maybe = null;          // nullable value type
        Console.WriteLine((text == null) + ", " + (maybe == null));
    }
}

Różnice w porównywaniu równości

W przypadku typów wartości operator == porównuje dane. W przypadku typów referencyjnych operator == zwykle porównuje tożsamość (czy jest to ten sam obiekt), chyba że został przesłonięty.

using System;

class Program
{
    static void Main()
    {
        int a = 5, b = 5;
        Console.WriteLine("ints: " + (a == b));   // True - same value

        object o1 = new object();
        object o2 = new object();
        Console.WriteLine("objects: " + (o1 == o2));   // False - different identity
    }
}

Wartości domyślne

Typy wartości mają domyślną wartość przypominającą zero (0, false), a typy referencyjne mają domyślnie wartość null.

using System;

class Program
{
    static void Main()
    {
        int defaultInt = default;
        bool defaultBool = default;
        string defaultString = default;
        Console.WriteLine(defaultInt + ", " + defaultBool + ", null? " + (defaultString == null));
    }
}

Podsumowanie całości

Wiedza o tym, czy typ jest typem wartości, czy typem referencyjnym, pozwala przewidzieć sposób kopiowania, dopuszczalność wartości null oraz to, jak metody mogą go modyfikować. Ma to kluczowe znaczenie dla tworzenia poprawnego kodu bez błędów.

using System;

struct Money { public decimal Amount; }
class Wallet { public decimal Amount; }

class Program
{
    static void Main()
    {
        Money m1 = new Money { Amount = 10 };
        Money m2 = m1; m2.Amount = 99;

        Wallet w1 = new Wallet { Amount = 10 };
        Wallet w2 = w1; w2.Amount = 99;

        Console.WriteLine("Money copy: " + m1.Amount + " (independent)");
        Console.WriteLine("Wallet ref: " + w1.Amount + " (shared)");
    }
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat typów wartości i typów referencyjnych.

Powtórzenie

Typy wartości (int, double, bool, struktury) przechowują dane bezpośrednio i są kopiowane podczas przypisania, natomiast typy referencyjne (klasy, napisy, tablice) przechowują odwołanie do obiektu na stercie i kopiują to odwołanie. Tylko typy referencyjne domyślnie dopuszczają wartość null, a sposób przypisywania i porównywania równości różni się w obu rodzinach typów.

using System;

struct V { public int N; }
class R { public int N; }

class Program
{
    static void Main()
    {
        V v1 = new V { N = 1 }; V v2 = v1; v2.N = 9;
        R r1 = new R { N = 1 }; R r2 = r1; r2.N = 9;
        Console.WriteLine(v1.N + " vs " + r1.N);
    }
}

Często zadawane pytania

Czy lekcja „Typy wartości a typy referencyjne” jest bezpłatna?

Tak — pełny tekst „Typy wartości a typy referencyjne” 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 „Typy wartości a typy referencyjne”?

Zobacz, jak każdy z nich jest przechowywany i kopiowany. Ć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 1 z 4.

Ile czasu zajmuje lekcja „Typy wartości a typy referencyjne”?

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. Typy wartości a typy referencyjne
  2. Boxing i unboxing
  3. Konwersje niejawne i jawne
  4. Klasa Convert i parsowanie
← Powrót do C# Academy