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

Zabalení je proces převodu typu hodnoty na typ 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ž pole CLR vyhodnotí typ hodnoty, zalomí hodnotu uvnitř System.Object instance a uloží ji na spravovanou haldu.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í představuje C# sjednocený pohled na systém typů, ve kterém může být hodnota libovolného typu považována 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 je proměnná i typu Integer zabalená a přiřazená objektu. oIn 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 pak může být nezabalený a přiřazený celočíselné iproměnné: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í, jak se používá zabalení C#v.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

Ve vztahu k jednoduchým přiřazením se zabalení a rozbalení počítají jako výpočetní náročné procesy.In relation to simple assignments, boxing and unboxing are computationally expensive processes. Když je hodnotový typ v krabici, musí být přidělen a vytvořen nový objekt.When a value type is boxed, a new object must be allocated and constructed. V menší míře je přetypování vyžadované pro rozbalení 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ýkon.For more information, see Performance.

ZabaleníBoxing

Zabalení se používá k ukládání typů hodnot v haldě uvolňování paměti.Boxing is used to store value types in the garbage-collected heap. Zabalení je implicitní převod typu hodnoty na typ 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 instanci objektu na haldě a zkopí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.

Zvažte následující deklaraci proměnné typu hodnoty:Consider the following declaration of a value-type variable:

int i = 123;

Následující příkaz implicitně aplikuje operaci zabalení na 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ýsledek tohoto příkazu vytváří odkaz ona objekt 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. Tato hodnota je kopií hodnoty typu hodnoty přiřazené 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ěno na následujícím obrázku převodu zabalení: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 proměnnými i a o.

Je také možné provést zabalení explicitně jako v následujícím příkladu, ale explicitní zabalení není nikdy vyžadováno: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

Tento příklad převede proměnnou i celého čísla na objekt o pomocí zabalení.This example converts an integer variable i to an object o by using boxing. Pak se hodnota uložená v proměnné i změní z 123 na 456.Then, the value stored in the variable i is changed from 123 to 456. Příklad ukazuje, že původní typ hodnoty a zabalený objekt používají oddělené umístění paměti, a proto může ukládat jiné 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 na 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. Rozbalení operace se skládá z těchto:An unboxing operation consists of:

  • Kontrola instance objektu, aby se zajistilo, ž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.

  • Zkopí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í převod rozbalení

Pro rozbalení typů hodnot, které mají být v době běhu úspěšné, musí být položka unboxed odkaz na objekt, který byl dříve vytvořen zabalením instance daného 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. Pokus o unbox null NullReferenceExceptionzpůsobí.Attempting to unbox null causes a NullReferenceException. Pokus o unbox odkazu na nekompatibilní typ hodnoty způsobí 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ého InvalidCastException.The following example demonstrates a case of invalid unboxing and the resulting InvalidCastException. Při try použití catcha se zobrazí chybová zpráva, když dojde k chybě.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;  

provede se převod 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