В .Net:
Часто ви не можете розраховувати на те, який тип змінної споживатиме функція, тому вам потрібно використовувати змінну об'єкта, яка розповсюджується від найменшого загального знаменника - в object
.
Однак object
є класом і зберігає його вміст як довідник.
List<int> notBoxed = new List<int> { 1, 2, 3 };
int i = notBoxed[1]; // this is the actual value
List<object> boxed = new List<object> { 1, 2, 3 };
int j = (int) boxed[1]; // this is an object that can be 'unboxed' to an int
Хоча обидва мають одну і ту ж інформацію, другий список є більшим і повільнішим. Кожне значення другого списку насправді є посиланням на значення, object
яке містить int
.
Це називається в коробці, тому що int
загортається object
. Коли його відкинути назад, int
це unboxed - перетворюється назад у його значення.
Для типів значень (тобто всіх structs
) це повільно і потенційно використовує набагато більше місця.
Для референтних типів (тобто всіх classes
) це набагато менше проблем, оскільки вони як і раніше зберігаються як посилання.
Подальша проблема типу типу в ящику полягає в тому, що не очевидно, що ви маєте справу з полем, а не зі значенням. Якщо ви порівнюєте два, structs
то ви порівнюєте значення, але коли ви порівнюєте два, classes
то (за замовчуванням) ви порівнюєте посилання - тобто це один і той же екземпляр?
Це може бути заплутаним при роботі з типовими кодами:
int a = 7;
int b = 7;
if(a == b) // Evaluates to true, because a and b have the same value
object c = (object) 7;
object d = (object) 7;
if(c == d) // Evaluates to false, because c and d are different instances
Їх легко обійти:
if(c.Equals(d)) // Evaluates to true because it calls the underlying int's equals
if(((int) c) == ((int) d)) // Evaluates to true once the values are cast
Однак слід бути обережним, маючи справу з коробчастими значеннями.