Udostępnij za pośrednictwem


Boks i pakowania (C# Programming Guide)

Boksie jest procesem konwertowania wartości typu typu object lub do dowolnego typu interfejsu implementowane przez tego typu wartości.Gdy środowisko CLR pola Typ wartości, otacza wartości wewnątrz elementu System.Object i zapisuje go w zarządzanych sterty.Pakowania wyodrębnia typ wartości z obiektu.Boksie jest niejawne; pakowania jest jawny.Pojęcie boksie i pakowania źródłową widoku unified C# typ systemu, wartość dowolnego typu mogą być traktowane jako obiekt.

W poniższym przykładzie zmienna integer i jest ramkach i przypisany do obiektu o.

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

Obiekt o można następnie unboxed i przypisana do zmiennej integer i:

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

Poniższe przykłady ilustrują, w jaki sposób boksie jest używana w języku 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

Wydajność

W odniesieniu do prostego przydziały boksie i pakowania są drogie w praktyce procesów.Po ramkach jest typ wartości, nowy obiekt musi być przydzielone oraz zbudowane.W mniejszym stopniu Obsada wymagane do pakowania jest również drogie obliczeniowo.Aby uzyskać więcej informacji, zobacz wydajności.

Boksie

Boksie jest używany do przechowywania typów wartości w stercie, zebrane garbage.Boksie jest niejawna konwersja wartości typu typu object lub do dowolnego typu interfejsu implementowane przez tego typu wartości.Boks typ wartości przydziela wystąpienie obiektu na stercie i skopiowanie wartości do nowego obiektu.

Rozważmy następującą deklarację zmiennej typu wartości:

int i = 123;

Poniższa instrukcja stosuje niejawnie operację boksie w zmiennej i:

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

Wynik tej instrukcji jest tworzenie odwołania do obiektu o, na stosie, który odwołuje się wartość typu int, na stercie.Ta wartość jest kopią wartość typu wartość przypisana do zmiennej i.Różnica między dwoma zmiennymi, i i o, przedstawiono na poniższym rysunku.

Konwersja boksie

BoxingConversion — grafika

Nigdy nie jest ona również możliwość wykonywania boksie jawnie w poniższym przykładzie, ale jawny boksie wymagane:

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

Opis

W tym przykładzie konwertuje zmiennej integer i do obiektu o za pomocą boksie.Następnie, wartość przechowywana w zmiennej i jest zmieniana z 123 do 456.W przykładzie pokazano, że oryginalny typ wartości i ramkach obiektów użyć lokalizacji pamięci oddzielnych i dlatego można przechowywać różne wartości.

Przykład

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 does not effect 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
*/

Poniższy przykład ilustruje przypadek nieprawidłowy pakowania i wynikającą z tego InvalidCastException.Za pomocą try i catch, jest wyświetlany komunikat o błędzie, gdy wystąpi błąd.

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);
        }
    }
}

Ten program wyświetla:

Specified cast is not valid. Error: Incorrect unboxing.

Jeśli zmienisz oświadczenie:

int j = (short) o;

do:

int j = (int) o;

konwersja zostanie wykonana, a otrzymasz dane wyjściowe:

Unboxing OK.

Rozpakowanej

Pakowania jest konwersja jawna od typu object do wartości typu lub z typu interfejsu typu wartości, która implementuje interfejs.Operacja rozpakowanej składa się z:

  • Sprawdzanie, czy wystąpienie obiektu, aby upewnić się, że jest boxed wartość typu danej wartości.

  • Kopiując wartość z instancji do zmiennej typu wartości.

Poniższe instrukcje wykazać zarówno boxing, jak i rozpakowanej operacji:

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

Na rysunku poniżej pokazano wynik poprzedniego sprawozdania.

Rozpakowanej konwersji

Grafika przedstawiająca konwersję unBoxing

Dla pakowania typów wartości została wykonana pomyślnie w czasie wykonywania element jest unboxed musi być odwołanie do obiektu, który został wcześniej utworzony przez boks wystąpienie tego typu wartości.Próby unbox null powoduje, że NullReferenceException.Próby unbox odwołanie do wartości niezgodne wpisz powoduje, że InvalidCastException.

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka to najlepsze źródło informacji dotyczących składni i zastosowania języka C#.

Sekcje pokrewne

Aby uzyskać więcej informacji:

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka to najlepsze źródło informacji dotyczących składni i zastosowania języka C#.

Zobacz też

Koncepcje

Podręcznik programowania C#