C# Academy · Lekcja

Boxing i unboxing

Poznaj koszt konwersji do typu object.

Lekcja 2 z 413 kroki

Boxing i unboxing 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.

Czym jest boxing?

Boxing umieszcza typ wartości wewnątrz obiektu, aby można było traktować go jak typ referencyjny. Instrukcja object o = 5; umieszcza wartość int w obiekcie na stercie.

using System;

class Program
{
    static void Main()
    {
        int n = 5;
        object o = n;   // boxing
        Console.WriteLine("Boxed value: " + o);
    }
}

Dlaczego zachodzi boxing

Boxing zachodzi za każdym razem, gdy typ wartości zostaje przypisany do zmiennej typu object (lub do interfejsu). Środowisko uruchomieniowe przydziela na stercie obiekt opakowujący, który zawiera kopię wartości.

using System;

class Program
{
    static void Main()
    {
        double d = 3.14;
        object boxed = d;   // boxing copies d into a heap object
        Console.WriteLine(boxed);
    }
}

Czym jest unboxing?

Unboxing wyodrębnia typ wartości z obiektu opakowującego za pomocą jawnego rzutowania. Typ rzutowania musi dokładnie odpowiadać typowi, który został opakowany.

using System;

class Program
{
    static void Main()
    {
        object o = 42;        // boxing
        int n = (int)o;        // unboxing
        Console.WriteLine("Unboxed: " + n);
    }
}

Unboxing wymaga właściwego typu

Należy wykonać unboxing do dokładnie pierwotnego typu. Próba wykonania unboxingu do innego typu powoduje zgłoszenie wyjątku InvalidCastException.

using System;

class Program
{
    static void Main()
    {
        object o = 100;
        try
        {
            long wrong = (long)o;   // InvalidCastException at runtime
            Console.WriteLine(wrong);
        }
        catch (InvalidCastException)
        {
            Console.WriteLine("Must unbox to int, not long");
        }
    }
}

Boxing tworzy kopię

Boxing kopiuje wartość. Późniejsza zmiana oryginału nie zmienia kopii umieszczonej w obiekcie opakowującym.

using System;

class Program
{
    static void Main()
    {
        int n = 1;
        object o = n;   // box copies 1
        n = 99;
        Console.WriteLine("original=" + n + ", boxed=" + o);
    }
}

Koszt operacji boxing

Każda operacja boxing przydziela pamięć na stercie i zwiększa obciążenie modułu odśmiecania pamięci. W często wykonywanych pętlach ten narzut może znacząco obniżyć wydajność.

using System;

class Program
{
    static void Main()
    {
        // Each iteration boxes an int -> many heap allocations
        object sumBox = 0;
        for (int i = 0; i < 5; i++)
        {
            int current = (int)sumBox + i;
            sumBox = current;   // box again
        }
        Console.WriteLine("Result: " + sumBox);
    }
}

Unikanie boxing za pomocą typów generycznych

Kolekcje generyczne, takie jak List<int>, przechowują typy wartości bez operacji boxing, w przeciwieństwie do starszej, niegenerycznej kolekcji ArrayList.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var list = new List<int>();   // no boxing
        list.Add(1);
        list.Add(2);
        int first = list[0];           // no unboxing
        Console.WriteLine("First: " + first);
    }
}

Boxing w przypadku interfejsów

Przypisanie struktury do zmiennej interfejsu również powoduje boxing, ponieważ odwołanie interfejsu musi wskazywać na obiekt na stercie.

using System;

class Program
{
    static void Main()
    {
        int n = 7;
        IComparable c = n;   // boxing to interface
        Console.WriteLine(c.CompareTo(10));
    }
}

Wykrywanie opakowanych typów

Przed bezpiecznym wykonaniem unboxingu można sprawdzić typ opakowanego obiektu w czasie wykonywania za pomocą is.

using System;

class Program
{
    static void Main()
    {
        object o = 3.5;
        if (o is double d)
            Console.WriteLine("It is a double: " + d);
        else
            Console.WriteLine("Not a double");
    }
}

Boxing podczas konkatenacji napisów

Łączenie typu wartości z napisami może powodować boxing. Interpolacja lub ToString jest często czytelniejsza, choć w tym przypadku boxing zwykle nie ma istotnego wpływu na wydajność.

using System;

class Program
{
    static void Main()
    {
        int count = 3;
        string msg = "Count is " + count;   // count is converted
        Console.WriteLine(msg);
    }
}

Podsumowanie całości

Boxing łączy światy typów wartości i typów referencyjnych, ale wiąże się z przydzielaniem pamięci. Należy preferować typy generyczne, aby go unikać, a unboxing wykonywać do dokładnie właściwego typu po bezpiecznym sprawdzeniu.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        object boxed = 256;
        if (boxed is int value)
            Console.WriteLine("Safely unboxed: " + value);

        var noBox = new List<int> { 1, 2, 3 };
        Console.WriteLine("Generic count: " + noBox.Count);
    }
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat operacji boxing i unboxing.

Powtórzenie

Boxing umieszcza typ wartości w obiekcie na stercie (np. object o = 5;), a unboxing wyodrębnia go za pomocą jawnego rzutowania do dokładnie pierwotnego typu. Boxing kopiuje wartość i przydziela pamięć, zwiększając obciążenie modułu odśmiecania pamięci. Aby unikać boxing, należy preferować kolekcje generyczne, takie jak List<int>, a do bezpiecznego unboxingu używać is.

using System;

class Program
{
    static void Main()
    {
        object boxed = 42;     // box
        int n = (int)boxed;     // unbox
        Console.WriteLine(n);
    }
}
Bezpłatny start

Ucz się C# dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
93
Lekcje
346

Często zadawane pytania

Czy lekcja „Boxing i unboxing” jest bezpłatna?

Tak — pełny tekst „Boxing i unboxing” 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 „Boxing i unboxing”?

Poznaj koszt konwersji do typu object. Ć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 „Boxing i unboxing”?

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