Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Boxing je proces převodu typu hodnoty na typ object nebo na jakýkoli typ rozhraní implementovaný tímto typem hodnoty. Když modul common language runtime (CLR) zabalí hodnotový typ do instance System.Object a uloží jej na spravovanou hromadu. Rozbalení extrahuje typ hodnoty z objektu. Boxování je implicitní; unboxování je explicitní. Koncept boxování a rozbalování je základem sjednoceného zobrazení systému typů jazyka C#, ve kterém může být hodnota libovolného typu považována za objekt.
V následujícím příkladu je celočíselná proměnná i a přiřazena k objektu o.
int i = 123;
// The following line boxes i.
object o = i;
Objekt o pak lze rozbalit a přiřadit k celočíselné proměnné i:
o = 123;
i = (int)o; // unboxing
Následující příklady ukazují, jak se boxování používá v jazyce 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 = [];
// 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];
}
Console.WriteLine($"Sum: {sum}");
// Output:
// Answer42True
// First Group:
// 1
// 2
// 3
// 4
// Second Group:
// 5
// 6
// 7
// 8
// 9
// Sum: 30
Výkon
V souvislosti s jednoduchými přiřazeními jsou boxování a rozbalení výpočetně náročné procesy. Pokud je typ hodnoty v rámečku, musí být nový objekt přidělen a vytvořen. Do menší míry je přetypování potřebné pro rozbalení také nákladné z hlediska výpočtů. Další informace naleznete v tématu Výkon.
Boxování
Boxing se používá k ukládání hodnotových typů v haldě s automatickým uvolňováním paměti. Boxing je implicitní převod hodnotového typu na typ object nebo na jakýkoli typ rozhraní implementovaný tímto hodnotovým typem. Boxování hodnotového typu vytváří instanci objektu na haldě a zkopíruje hodnotu do nového objektu.
Představte si následující deklaraci proměnné typu hodnota:
int i = 123;
Následující příkaz implicitně použije operaci boxingu na proměnné 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, v haldě. Tato hodnota je kopií hodnoty typu hodnoty přiřazené proměnné i. Rozdíl mezi dvěma proměnnými, i a o, je znázorněn na následujícím obrázku boxerského převodu.
Je také možné provést boxování explicitně jako v následujícím příkladu, ale explicitní boxování není nikdy nutné:
int i = 123;
object o = (object)i; // explicit boxing
Příklad
Tento příklad převede celočíselnou proměnnou i na objekt o pomocí boxování. Potom se hodnota uložená v proměnné i změní z 123 na 456. Příklad ukazuje, že původní typ hodnoty a boxovaný objekt používají samostatná umístění paměti, a proto mohou ukládat různé hodnoty.
// Create an int variable
int i = 123;
// Box the value type into an object reference
object o = i; // boxing
// Display the initial values
Console.WriteLine($"Value of i: {i}");
Console.WriteLine($"Value of boxed object o: {o}");
// Modify the original value type
i = 456;
// Display the values after modification
Console.WriteLine("\nAfter changing i to 456:");
Console.WriteLine($"Value of i: {i}");
Console.WriteLine($"Value of boxed object o: {o}");
// Output:
// Value of i: 123
// Value of boxed object o: 123
// After changing i to 456:
// Value of i: 456
// Value of boxed object o: 123
Rozbalení
Unboxing je explicitní převod z typu object na hodnotový typ nebo z typu rozhraní na hodnotový typ, který implementuje toto rozhraní. Operace rozbalení se skládá z:
Zkontrolujte instanci objektu a ujistěte se, že se jedná o zabalenou hodnotu zadaného typu hodnoty.
Kopírování hodnoty z instance do proměnné hodnotového typu.
Následující příkazy ukazují operace boxingu i unboxingu:
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
Následující obrázek znázorňuje výsledek předchozích tvrzení:
Aby bylo rozbalení hodnotových typů úspěšné v běhu programu, musí být položka, která se rozbaluje, odkazem na objekt, jenž byl dříve vytvořen zaboxováním instance tohoto typu hodnoty. Pokus o rozbalení null způsobí NullReferenceException. Pokus o rozbalování odkazu na nekompatibilní typ hodnoty vyvolá InvalidCastException.
Příklad
Následující příklad ukazuje případ neplatného rozbalení a výsledného InvalidCastException. Při použití try a catchse při výskytu chyby zobrazí chybová zpráva.
class TestUnboxing
{
static void Main()
{
int i = 123;
object o = i; // implicit boxing
try
{
int j = (short)o; // attempt to unbox
Console.WriteLine("Unboxing OK.");
}
catch (InvalidCastException e)
{
Console.WriteLine($"{e.Message} Error: Incorrect unboxing.");
}
}
}
Tento program vypíše:
Specified cast is not valid. Error: Incorrect unboxing.
Pokud změníte výrok:
int j = (short)o;
Do:
int j = (int)o;
Převod se provede a zobrazí se výstup:
Unboxing OK.
Specifikace jazyka C#
Další informace najdete ve specifikaci jazyka C# . Specifikace jazyka je konečným zdrojem syntaxe a použití jazyka C#.
Viz také
- odkazové typy
- typy hodnot