# «Boxing» (Решение)

## Ответ

```
Foo
Foo
Foo
Bar
Baz
Foo
```

## Объяснение

Ключевым моментом в понимании примера является тот факт, что при вызове `Console.WriteLine` используется перегруженный вариант метода, принимающий аргумент типа `object`. Поэтому передаваемая в него структура упаковывается. Это означает, что в управляемой куче создаётся копия структуры, метод `ToString()` отрабатывает для упакованной копии. Теперь разберём пример по строчкам:

```csharp
var foo = new Foo();
Console.WriteLine(foo); // Displays "Foo" (value == 0)
Console.WriteLine(foo); // Displays "Foo" (value == 0)
```

Мы создали экземпляр структуры `Foo` и дважды выполнили для него `Console.WriteLine(foo)`. Дважды выполнилась копирование и упаковка структуры, `ToString()` вызвалось для копии, не тронув оригинал. Изначально `Foo.value == 0`, так что в обоих случаях выведется `"Foo"`.

```csharp
object bar = foo;
object qux = foo;
object baz = bar;
```

Тут мы явно выполняем упаковку структуры. Объекты `bar` и `qux` указывают на разные копии структуры, т.к. мы выполнили две отдельных операции упаковки. Объект `baz` указывает на ту же копию структуры, что и `bar`, т.к. в третьей строчке мы просто выполнили копирование ссылки.

```csharp
Console.WriteLine(baz); // Displays "Foo" (value == 0)
Console.WriteLine(bar); // Displays "Bar" (value == 1)
Console.WriteLine(baz); // Displays "Baz" (value == 2)
```

В этих трёх строчках мы работаем с одной и той же копией структуры, обращаясь к ней по ссылке (`bar` и `baz` представляют собой одну и ту же ссылку).

```csharp
Console.WriteLine(qux); // Displays "Foo" (value == 0)
```

А в этой строчке мы работаем с копией структуры, для которой метод `ToString()` ещё ни разу не вызывался. Поэтому выведется `"Foo"`.

[Задача](https://andreyakinshin.gitbook.io/problembookdotnet/ru/valuetypes/boxing-p)
