Zabalení a rozbalení (Průvodce programováním v C#)Boxing and Unboxing (C# Programming Guide)

Zabalení je proces převodu typ hodnoty typu object nebo na libovolný typ rozhraní implementovaný tímto typem hodnoty.Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. Když modul CLR pole typu hodnoty, obtéká hodnotu uvnitř System.Object instance a uloží ji na spravované haldě.When the CLR boxes a value type, it wraps the value inside a System.Object instance and stores it on the managed heap. Rozbalení extrahuje typ hodnoty z objektu.Unboxing extracts the value type from the object. Zabalení je implicitní; Rozbalení je explicitní.Boxing is implicit; unboxing is explicit. Pojem zabalení a rozbalení základem sjednocené zobrazení C# systému typů, ve kterém lze považovat hodnotu libovolného typu za objekt.The concept of boxing and unboxing underlies the C# unified view of the type system in which a value of any type can be treated as an object.

V následujícím příkladu proměnná integer i je boxed a přiřazené k objektu o.In the following example, the integer variable i is boxed and assigned to object o.

int i = 123;
// The following line boxes i.
object o = i;  

Objekt o lze potom rozbalit a přiřadit k proměnné celého čísla i:The object o can then be unboxed and assigned to integer variable i:

o = 123;
i = (int)o;  // unboxing

Následující příklady ilustrují použití zabalení v jazyce C#.The following examples illustrate how boxing is used in C#.

// String.Concat example.
// String.Concat has many versions. Rest the mouse pointer on 
// Concat in the following statement to verify that the version
// that is used here takes three object arguments. Both 42 and
// true must be boxed.
Console.WriteLine(String.Concat("Answer", 42, true));


// List example.
// Create a list of objects to hold a heterogeneous collection 
// of elements.
List<object> mixedList = new List<object>();

// Add a string element to the list. 
mixedList.Add("First Group:");

// Add some integers to the list. 
for (int j = 1; j < 5; j++)
{
    // Rest the mouse pointer over j to verify that you are adding
    // an int to a list of objects. Each element j is boxed when 
    // you add j to mixedList.
    mixedList.Add(j);
}

// Add another string and more integers.
mixedList.Add("Second Group:");
for (int j = 5; j < 10; j++)
{
    mixedList.Add(j);
}

// Display the elements in the list. Declare the loop variable by 
// using var, so that the compiler assigns its type.
foreach (var item in mixedList)
{
    // Rest the mouse pointer over item to verify that the elements
    // of mixedList are objects.
    Console.WriteLine(item);
}

// The following loop sums the squares of the first group of boxed
// integers in mixedList. The list elements are objects, and cannot
// be multiplied or added to the sum until they are unboxed. The
// unboxing must be done explicitly.
var sum = 0;
for (var j = 1; j < 5; j++)
{
    // The following statement causes a compiler error: Operator 
    // '*' cannot be applied to operands of type 'object' and
    // 'object'. 
    //sum += mixedList[j] * mixedList[j]);

    // After the list elements are unboxed, the computation does 
    // not cause a compiler error.
    sum += (int)mixedList[j] * (int)mixedList[j];
}

// The sum displayed is 30, the sum of 1 + 4 + 9 + 16.
Console.WriteLine("Sum: " + sum);

// Output:
// Answer42True
// First Group:
// 1
// 2
// 3
// 4
// Second Group:
// 5
// 6
// 7
// 8
// 9
// Sum: 30

VýkonPerformance

Vzhledem k jednoduchým přiřazením jsou zabalení a rozbalení výpočetně náročné procesy.In relation to simple assignments, boxing and unboxing are computationally expensive processes. Když je typ hodnoty v poli, musí být přiděleny a konstruovány nový objekt.When a value type is boxed, a new object must be allocated and constructed. V menší míře je přetypování potřebné pro rozbalení je také nákladné výpočetně.To a lesser degree, the cast required for unboxing is also expensive computationally. Další informace najdete v tématu výkonu.For more information, see Performance.

ZabaleníBoxing

Zabalení slouží k uložení typů hodnot haldy uvolňování.Boxing is used to store value types in the garbage-collected heap. Zabalení je implicitní převod typ hodnoty typu object nebo na libovolný typ rozhraní implementovaný tímto typem hodnoty.Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Zabalení typu hodnoty přiděluje instance objektu na haldě a kopíruje hodnotu do nového objektu.Boxing a value type allocates an object instance on the heap and copies the value into the new object.

Vezměte v úvahu následující deklarace proměnné hodnotového typu:Consider the following declaration of a value-type variable:

int i = 123;

Následující příkaz se implicitně týká operace zabalení pro proměnnou i:The following statement implicitly applies the boxing operation on the variable i:

// Boxing copies the value of i into object o.
object o = i;  

Výsledkem tohoto příkazu je vytvoření odkazu na objekt o, v zásobníku, který odkazuje na hodnotu typu int, na haldě.The result of this statement is creating an object reference o, on the stack, that references a value of the type int, on the heap. Tuto hodnotu je kopií hodnoty hodnotového typu přiřazena k proměnné i.This value is a copy of the value-type value assigned to the variable i. Rozdíl mezi dvěma proměnnými, i a o, je znázorněn na následujícím obrázku převod na uzavřené určení:The difference between the two variables, i and o, is illustrated in the following image of boxing conversion:

Obrázek znázorňující rozdíl mezi i a o proměnné.

Je také možné provést zabalení explicitně jako v následujícím příkladu, ale nikdy není vyžadováno explicitní zabalení:It is also possible to perform the boxing explicitly as in the following example, but explicit boxing is never required:

int i = 123;
object o = (object)i;  // explicit boxing

PopisDescription

V tomto příkladu se převede celočíselná proměnná i objektu o pomocí uzavřeného určení.This example converts an integer variable i to an object o by using boxing. Následně je hodnota uložená v proměnné i se změnil z 123 k 456.Then, the value stored in the variable i is changed from 123 to 456. Příklad ukazuje, že typ původní hodnoty a zabalený objekt používají samostatná paměťová místa a proto mohou uchovávat různé hodnoty.The example shows that the original value type and the boxed object use separate memory locations, and therefore can store different values.

PříkladExample

class TestBoxing
{
    static void Main()
    {
        int i = 123;

        // Boxing copies the value of i into object o.
        object o = i;  

        // Change the value of i.
        i = 456;  

        // The change in i doesn't affect the value stored in o.
        System.Console.WriteLine("The value-type value = {0}", i);
        System.Console.WriteLine("The object-type value = {0}", o);
    }
}
/* Output:
    The value-type value = 456
    The object-type value = 123
*/

RozbaleníUnboxing

Rozbalení je explicitní převod z typu object k typ hodnoty nebo z typu rozhraní na typ hodnoty, která implementuje rozhraní.Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. Operace rozbalení se skládá ze:An unboxing operation consists of:

  • Kontrola instance objektu, abyste měli jistotu, že se jedná o zabalenou hodnotu daného typu hodnoty.Checking the object instance to make sure that it is a boxed value of the given value type.

  • Kopírování hodnoty z instance do proměnné typu hodnoty.Copying the value from the instance into the value-type variable.

Následující příkazy ukazují operace zabalení a rozbalení:The following statements demonstrate both boxing and unboxing operations:

int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;   // unboxing

Následující obrázek ukazuje výsledek předchozích příkazů:The following figure demonstrates the result of the previous statements:

Obrázek znázorňující unboxingového převodu.

Pro rozbalení typů hodnot v době spuštění úspěšné, musí být rozbalená položka odkazem na objekt, který byl dříve vytvořen zabalením instance tohoto typu hodnoty.For the unboxing of value types to succeed at run time, the item being unboxed must be a reference to an object that was previously created by boxing an instance of that value type. Při pokusu o rozbalení null způsobí, že NullReferenceException.Attempting to unbox null causes a NullReferenceException. Při pokusu o vybalení odkazu na nekompatibilní hodnotu způsobí typ InvalidCastException.Attempting to unbox a reference to an incompatible value type causes an InvalidCastException.

PříkladExample

Následující příklad ukazuje případ neplatného rozbalení a výsledné InvalidCastException.The following example demonstrates a case of invalid unboxing and the resulting InvalidCastException. Pomocí try a catch, když dojde k chybě, zobrazí se chybová zpráva.Using try and catch, an error message is displayed when the error occurs.

class TestUnboxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing

        try
        {
            int j = (short)o;  // attempt to unbox

            System.Console.WriteLine("Unboxing OK.");
        }
        catch (System.InvalidCastException e)
        {
            System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
        }
    }
}

Výstup tohoto programu:This program outputs:

Specified cast is not valid. Error: Incorrect unboxing.

Pokud změníte příkaz:If you change the statement:

int j = (short) o;  

nato:

int j = (int) o;  

Převod se provede, a zobrazí se výstup:the conversion will be performed, and you will get the output:

Unboxing OK.

Specifikace jazyka C#C# Language Specification

Další informace najdete v tématu Specifikace jazyka C#.For more information, see the C# Language Specification. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.The language specification is the definitive source for C# syntax and usage.

Další informace:For more information:

Viz také:See also