Является ли все в .NET объектом? - PullRequest
48 голосов
/ 12 января 2009

Пожалуйста, помогите нам разрешить спор о "Почти" все является объектом ( ответ на вопрос переполнения стека Как новичок, есть ли что-то, что я должен остерегаться, прежде чем изучать C # ). Я думал, что это так, потому что все в Visual Studio, по крайней мере, выглядит как структура. Пожалуйста, опубликуйте ссылку, чтобы она не стала "современным ослом" ( This American Life ).

Обратите внимание, что этот вопрос относится к C #, а не обязательно к .NET, и к тому, как он обрабатывает данные под капотом (очевидно, это все 1 и 0).

Вот комментарии к «все является объектом»:

  • Эх, нет, это не так. - Двоичный Беспорядок
  • Я бы хотел пример ... - scotty2012
  • не все происходит от базовый тип объекта? - Ризель
  • Большинство вещей являются объектами ... - Омар Kooheji
  • Типы значений, целые, двойные, объект ссылки (не объекты их Я) и т. д. не являются объектами. Они могут быть "упакованным", чтобы выглядеть как объекты (например, i.ToString ()) но на самом деле они примитивные типы. Изменить запись на «РЫЧАГ - это все» Я уберу понижающий голос - Бинарный Worrier
  • Я ценю разъяснения. я думаю, что самый низкий уровень, который вы можете взаимодействовать с, скажем, int, в C # есть как структура, которая не является объектом? - http://msdn.microsoft.com/en-us/library/ms173109.aspx - Ризель
  • Не наследует Int32 от ValueType который наследует от объекта? Если так, несмотря на поведение, int является объект. - Крис Фармер
  • Нет, коробочный тип для int наследуется из ValueType, который наследуется от Объект. Они не объекты в традиционный смысл, потому что а) Int это не ссылка на int, это инт. б) целые не мусор собраны. Если вы объявите Int32, тогда это int 4 байта на стек, конец истории - Binary Worrier

Определение объекта: «Объект» как наследник класса System.Object и «Объект» как экземпляр типа против «Объект» как ссылочный тип. "

Ответы [ 17 ]

79 голосов
/ 12 января 2009

Проблема здесь в том, что это действительно два вопроса - один вопрос о наследовании, и в этом случае ответ «почти все», а другой о ссылочном типе против типа значения / памяти / бокса, в этом случае ответ это "нет".

Наследование:

В C # верно следующее:

  • Все типы значений, включая перечисления и обнуляемые типы, являются производными от System.Object.
  • Все типы классов, массивов и делегатов получены из System.Object.
  • Типы интерфейса не являются производными от System.Object. Все они могут быть преобразованы в System.Object, но интерфейсы являются производными только от других типов интерфейсов, а System.Object не является типом интерфейса.
  • Типы указателей не являются производными от System.Object, и ни один из них не может быть напрямую преобразован в System.Object.
  • Типы параметров «открытого» типа также не являются производными от System.Object. Типы параметров типа не являются производными от чего-либо; аргументы типа ограничены, чтобы быть производными от эффективного базового класса, но сами по себе они не являются «производными» от чего-либо.

С запись MSDN для System.Object :

Поддерживает все классы в .NET Структура иерархии классов и обеспечивает низкоуровневые сервисы для производных классов. Это основной базовый класс всех классы в .NET Framework; это корень иерархии типов.

Языки, как правило, не требуют класс для объявления наследства Объект, потому что наследование неявное.

Потому что все классы в .NET Каркас получен из объекта, каждый метод, определенный в объекте класс доступен во всех объектах в система. Производные классы можно и делать переопределить некоторые из этих методов.

Так что не каждый тип в C # является производным от System.Object. И даже для тех типов, которые есть, вы все равно должны заметить разницу между ссылочными типами и типами значений , поскольку они обрабатываются совершенно по-разному.

Бокс:

Хотя типы значений наследуют от System.Object, они обрабатываются по-разному в памяти по сравнению с ссылочными типами, и семантика того, как они передаются через методы в вашем коде, также различна. Действительно, тип значения не рассматривается как объект (ссылочный тип), пока вы явно не проинструктируете свое приложение, поместив его в качестве ссылочного типа. Смотрите более подробную информацию о боксе в C # здесь .

30 голосов
/ 13 августа 2009

Немного опоздал на вечеринку, но я наткнулся на это в результатах поиска на SO и подумал, что ссылка ниже поможет будущим поколениям:

Эрик Липперт очень подробно обсуждает это , с гораздо лучшим (квалифицированным) утверждением:

Способ исправить этот миф состоит в том, чтобы просто заменить «происходит от» на «конвертируемо в» и игнорировать типы указателей: каждый не указательный тип в C # конвертируется в объект.

Суть этого, если вы ненавидите читать хорошо иллюстрированные объяснения от людей, которые пишут языки программирования, состоит в том, что (помимо указателей) такие вещи, как интерфейс или объявления обобщенных типов параметров («T»), не являются объектами, а гарантированно будет обрабатываться как объекты во время выполнения, потому что у них есть определенный экземпляр, который будет объектом. Другие типы (тип, перечисление, делегат, классы и т. Д.) Являются объектами. Включая типы значений, которые можно упаковать в объект, как обсуждали другие ответы.

16 голосов
/ 12 января 2009

Некоторые люди здесь имеют странное представление о том, что такое «объект» в объектно-ориентированном программировании. Для того, чтобы что-то было объектом, оно не должно быть ссылочным типом или, в более общем смысле, следовать любой формальной реализации.

Все это означает, что вы можете действовать как первоклассный гражданин в объектно-ориентированном мире. Поскольку вы можете делать это со значениями в C # (благодаря автоматической блокировке), все действительно является объектом. В некоторой степени это верно даже для функций (но, возможно, не для классов).

Является ли это актуальным на практике, это другой вопрос, но это общая проблема с ООП, которую я замечаю еще раз. Никто не имеет четкого представления об определении ООП (да, большинство людей согласны с тем, что оно как-то связано с полиморфизмом, наследованием и инкапсуляцией, некоторые добавляют «абстракцию» для хорошей меры).

С точки зрения использования каждое значение в C # обрабатывается как объект. Тем не менее, мне нравится принятый в настоящее время ответ. Он предлагает оба технически важных аспекта.

Обратите внимание, что в других контекстах, например, В C ++ подчеркиваются другие аспекты, поскольку C ++ не обязательно является объектно-ориентированным и, более того, гораздо больше внимания уделяется аспектам низкого уровня. Поэтому различие между объектами, POD и встроенными примитивами иногда имеет смысл (а иногда и нет).

7 голосов
/ 12 января 2009

Все они рассматриваются как объекты, но они не все объекты. Путаница приходит с Autoboxing.

См. Это для получения дополнительной информации: http://en.wikipedia.org/wiki/Object_type

Абстракция, по-видимому, смущает людей.

6 голосов
/ 12 января 2009

Я думал, что типы значений НЕ являются объектами. Они по-разному хранятся в памяти CLR - типы значений хранятся в стеке, а объекты хранятся в куче. Вы можете привести типы значений к ссылочному типу, чтобы они действовали как объект, но CLR извлекает значение из стека, помещает его в объект и сохраняет в куче. Вот что происходит, когда вы «коробляете» переменную.

6 голосов
/ 12 января 2009

Вы путаете объект со значением или ссылкой. По сути, все является объектом. Int - это объект, но это также тип значения. Экземпляр класса - это объект, но это также ссылочный тип.

Методы не являются ни объектами, ни свойствами. Просто оперируй объектами. И да, почти все наследуется от класса объекта.

5 голосов
/ 12 января 2009

В C # (и в ООП в целом) у нас есть типы (класс - ссылка, структура - значение и т. Д.). Это определения. А «объект» - это конкретный экземпляр данного типа.

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

Путаница, скорее всего, начинается с неправильного выбора названия самого базового класса для всего. В .NET это класс Object.

3 голосов
/ 12 января 2009

От: Типы значений (C # Reference) - MSDN 3.5

Все типы значений получены неявно из System.ValueType.

От: Тип значения Класс - MSDN 3.5

ValueType переопределяет виртуальный методы из объекта с более соответствующие реализации для значения типы.

От: Класс Enum - MSDN 3.5

Этот класс наследует от ValueType

Иерархия наследования выглядит следующим образом:

  • System.Object
    • System.ValueType
      • System.Enum

Вывод: Все является объектом

3 голосов
/ 12 января 2009

На основании всех книг, которые я прочитал, все в C # является объектом.

Некоторые являются ссылочными, другие являются типом значения. Тип значения объекта наследуется от класса ValueType . Они ведут себя по-разному, но по своей сути ... объекты.

Это причина, по которой вы можете хранить Int32 в переменной объекта, а также все, что вы можете создать в .NET.

Для более подробной информации ... посмотрите на следующее: http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.71).aspx

Все типы значений получены неявно из класса Object.

2 голосов
/ 13 января 2009

Хотя все, кажется, сосредоточены на обсуждении типов значений и ссылочных типов, мы забываем об одном типе в C #, который не является ни ссылкой, ни значением, он не является производным от объекта и не может быть приведен к объекту : указатели.

В отличие от значений и ссылочных типов, указатели нельзя приводить к объекту.

Согласно документации MSDN о типах указателей C # ,

Типы указателей не наследуются от объект и никаких преобразований не существует между типами указателя и объектом. Кроме того, бокс и распаковка не указатели поддержки. Тем не менее, вы можете конвертировать между разными указателями типы и между типами указателей и целочисленные типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...