Подтвердить что ты не робот

Если структура не может наследовать другой класс или структуру, почему Int32 имеет метод ToString()?

int a = 2;

Console.WriteLine(a.ToString()); // displays 2

// definition of ToString() here - public override string ToString();

Теперь, вот некоторые из моих понятий:

  • Все классы в .net получают метод ToString(), который наследуется от класса Object.
  • Структура не может быть получена из класса или другой структуры. int - это структура типа Int32, которая получает пару методов ToString() [With Parameters] из интерфейсов, которые она реализует.
  • В struct Int32 имеется функция
ToString() [без параметров]

Согласно http://msdn.microsoft.com/en-us/library/system.int32.tostring.aspx,

struct Int32 переопределяет метод ValueType.ToString()

Если структура не может наследовать какой-либо класс или структуру, можете ли вы объяснить, как этот метод ToString() доступен для Int32?

4b9b3361

Ответ 1

Если структура не может наследовать некоторый класс или структуру,

Это неверно. Все структуры (и встроенные типы значений, такие как System.Int32, System.Single и т.д.) Всегда неявно наследуют от System.ValueType (который, в свою очередь, наследует от System.Object).

Однако вы не можете создать структуру, которая наследуется от всего остального.

Это четко указано в спецификации языка С#, 4.1.1:

4.1.1 Тип System.ValueType

Все типы значений неявно наследуются от класса System.ValueType, который, в свою очередь, наследуется от объекта класса. Невозможно, чтобы любой тип выводился из типа значения, поэтому типы значений неявно закрыты (§10.1.1.2).

Затем, позже (4.1.3) struct явно определяется как тип значения:

4.1.3 Типы конструкций

Тип структуры - тип значения, который может объявлять константы, поля, методы, свойства, индексы, операторы, конструкторы экземпляров, статические конструкторы и вложенные типы.

Ответ 2

Int32 реализует IFormattable, который определяет метод ToString

Ответ 3

Каждое определение типа, производного от ValueType, фактически определяет два разных типа вещей во время выполнения: тип объекта кучи (который происходит от ValueType и, в свою очередь, от Object и который содержит информацию о встроенном типе) и тип места хранения (который не содержит информации о встроенном типе, а вместо этого требует, чтобы используемый им код должен иметь некоторые другие способы узнать, что это такое). Экземпляр типа объекта кучи содержит поле типа хранилища, а код, который пытается получить доступ к this, получит доступ к этому полю. Если тип значения применяется неявно или явно к месту хранения ссылочного типа, система создаст новый объект кучи с соответствующим типом и скопирует все общедоступные и частные поля типа значения в соответствующие поля в кучном объекте. Если объект кучи отбрасывается в хранилище данных типа значения, все общедоступные и частные поля из объекта кучи будут скопированы в хранилище значений типа.

Если делается попытка использовать любой метод Object или интерфейса для объекта кучи типа значения, метод будет вызываться так же, как и любой другой метод кучного объекта. Если попытка сделана в месте хранения типа значения, для любого метода, отличного от GetType, компилятор будет генерировать специальный "ограниченный" код операции, который сообщает время выполнения типа хранилища и указывает время выполнения вызова адрес метода, соответствующего этому типу. Поскольку у компилятора будет доступный тип местоположения хранилища, и время выполнения может использовать его для поиска соответствующего метода, соответствующий метод можно вызвать непосредственно в месте хранения, не создавая сначала новый объект кучи. GetType является единственным заметным исключением; поскольку он работает, исследуя информацию о типе, встроенную в объект, он может работать только на вещи, которые имеют встроенную информацию о типе. Следовательно, его аргумент будет преобразован в форму кучи объекта перед вызовом; GetType затем сможет исследовать информацию о встроенном типе этого объекта кучи.