Мы знаем, что все типы происходят от объекта. который является ссылочным типом. Мой вопрос почему int - который является типом значения - наследуется от ссылки type Object? Это возможно?
System.Int32
происходит от System.ValueType
, также как и все структуры на C#. Эта цепочка наследования разрешена компилятором, который является тем же самым механизмом, который запрещает вам наследование в любом другом struct
. Общее время выполнения (CLR) общего языка имеет специальную семантику для типов, которые производятся от System.ValueType
. System.ValueType
сам по себе не является типом значения, это ссылочный тип, который формирует базовый класс для всех структур. Хотя эта иерархия наследования существует, она не должна гарантировать ничего о том, как объекты будут выложены в памяти.
Почему нам нужно поле при передаче функции int, которая ожидает объект как параметр? Обычно со ссылками, когда вам нужно передать объект производного типа в качестве параметра для функции ожидающего объекта базового типа, вам не нужно ничего делать. Почему ящик здесь?
Потому что, хотя любой struct
в конечном счете происходит от object
, он фактически трактуется по-разному по времени выполнения. Все структуры рассматриваются как блок данных, у них нет указателя таблицы методов или индекса блока синхронизации, который имеет каждый ссылочный тип в .NET. Вот почему любой тип значения, который передается методу, принимающему object
, должен быть помещен в бокс, поскольку дополнительные данные должны быть добавлены к нему, чтобы фактически стать полностью квалифицированным типом object
. Типы значений не только помещаются в бокс, когда они передаются как object
, но и в коробке, например, когда вы вызываете метод, который был добавлен в ваш struct
в результате реализации интерфейса. Этот тип значения должен быть помещен в бокс, чтобы получить фактический указатель таблицы метода к методу, который необходимо вызвать.
Вы можете увидеть это с небольшим примером:
void Main()
{
IFoo m = new M();
m.X();
}
public struct M : IFoo
{
public void X() { }
}
public interface IFoo
{
void X();
}
даст следующий IL (составитель в режиме выпуска):
IL_0000: ldloca.s 00
IL_0002: initobj UserQuery.M
IL_0008: ldloc.0
IL_0009: box UserQuery.M
IL_000E: callvirt UserQuery+IFoo.X
IL_0013: ret
'все типы происходят от Object' __isn't всегда верно. –
принятый ответ на [этот другой вопрос] (http://stackoverflow.com/questions/1682231/how-do-valuetypes-derive-from-object-referencetype-and-still-be-valuetypes) гораздо более уместен –
[Не все происходит от объекта] (http://i1.blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx) –