Почему большинство типов в C# наследуются от System.Объект? [дубликат]

этот вопрос уже есть ответ здесь:

Я проверял типы int и float в C#, и даже у них есть "ToString" и т. д., методы, означающие, что они унаследованы от системы.Объект. Но разве это не вызывает хит производительности? Я понимаю, что они не создавал базовые типы, такие как объекты int в java из-за производительности. Разве это правило не относится и к .NET? И если да, то означает ли это, что .NET медленнее, чем Java? Но практически это не так, потому что программы, которые я сделал на C#, работают лучше, чем те, которые я сделал на Java. Так что я не понимаю?

4 ответов


очень важно понимать различия между типами значений и ссылочными типами. Суть различия заключается в том, каково значение выражения типа.

считаем:

int x = 10;
SomeClass y = new SomeClass();

здесь значение x действительно 10-биты для 10 заканчиваются в памяти, связанной с переменной x.

значение y это ссылка - способ добраться до отдельного объекта в память.

разница становится очень важной, когда вы используете назначение, особенно с mutable ссылка типа:

int x1 = 10;
int x2 = x1;
SomeClass y1 = new SomeClass();
SomeClass y2 = y1;

y1.SomeProperty = "Fred";
Console.WriteLine(y2.SomeProperty);

в обоих случаях стоимостью переменной копируется в присваивание-so x2значение 10;y2's значение является ссылка на тот же объект. Поэтому, когда данные объекта изменяются через свойство в предпоследнем, вы все равно можете увидеть эту разницу через y2.

вы редко пишите z1.SomeProperty = ..., когда z1 - это переменная типа значения, так как большинство типов значений неизменяемые. (Вы не можете изменить значение самих данных - вы должны явно назначить новое значение переменной.) Если вы сделал, однако вы не увидите никаких изменений через переменные, которые были ранее инициализированы с помощью присваивания z1 потому что стоимостью был бы скопирован в этом назначение.

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


теперь C# и .NET имеют единую систему типов, такую, что даже типы значений наследование С System.Object. Это означает, что вы можете вызвать все сообщения из Object на значения типа значения. иногда это требует бокса (преобразование значения типа значения в Object), а иногда нет... Я не буду переходите ко всем правилам прямо сейчас. Важно отметить, что если тип значения переопределяет метод объекта (например,ToString или GetHashCode) стоимостью не нужно быть в коробке, чтобы вызвать метод.

во время бокса тут производительности, это обычно завышено в моем опыте. В наши дни с дженериками бокс не так нужен, как раньше, но до тех пор, пока вы используете его разумно, он вряд ли станет значительным проблема производительности в приложении.


EDIT: относительно игр, производительности и обучения немного за раз...

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

лично я считаю, что консольные приложения являются самым простым способом изучения большинства основных новых концепций - будь то языковые функции, файл IO, коллекции, веб-службы, потоки и т. д. Очевидно, что для таких вещей, как" изучение Windows Forms", вы не можете сделать это с консольным приложением, но это действительно помогает, если ничего кроме части Windows Forms является новым для вас.

поэтому я настоятельно рекомендую вам изучить основы C# - такие вещи , как типы значений и ссылочные типы работают, как работает передача параметров, дженерики, классы, наследование и т. д. - Прежде чем переходить к играм. Это может показаться дополнительной работой, но это, скорее всего,сохранить время позднее. Когда что-то ведет себя не так, как вы ожидаете, вы узнаете, как язык работает, так что вы можете сосредоточиться на API вести себя по-разному и т. д. Попытка узнать одну вещь за раз делает весь процесс более плавным, в моем опыт.

в частности, требования к производительности игр означают, что иногда стоит писать очень неидиоматический C#. Такие вещи, как предварительное распределение объектов и их повторное использование там, где вы обычно создаете новые объекты... даже создание изменяемых структур, которые я бы в значительной степени никогда do в нормальном развитии. В критическом игровом цикле бокс или создание любых объектов вообще может быть плохая идея-но это не значит, что эти вещи "дороги" в нормальные рамки. Это очень важно что вы понимаете, когда эти вещи уместны, а когда нет... а если ты ... --23-->старт С разработкой игр вы получите несбалансированный взгляд на эти вещи, ИМО. Вы также потенциально попытаетесь микро-оптимизировать области, где вы действительно не нужно - но если у вас есть твердое заземление в C# и .NET для начала, вы будете в лучшем положении, чтобы получить все перспектива.


пока все объекты появляется происходит от System.Object, тогда для всех практических целей они are полученные от System.Object. Под капотом вещи оптимизированы в Совершенство, так что int - это всего лишь четыре-байт int большую часть времени, но это объект, когда он должен быть объектом. Вот что!--5-->бокс - все.

компилятор и время выполнения работают очень и очень трудно, чтобы убедиться, что примитивные типы не перегружены большим количеством лишнего багажа по размеру или функции. В то же время обеспечиваются все правила, необходимые для соответствия спецификации C# и иерархии объектов. Иногда компилятор принимает ярлыки, иногда время выполнения делает работу.


одно из преимуществ наличия общего базового класса означает, что вы можете написать такой метод, как public void DoSomething (объект объекта) { .... }

и по существу пройти во что-нибудь.

Не уверен в аспекте производительности, хотя.


EDIT: чтобы прояснить мою позицию по боксу: Джон сказал это хорошо, когда он попросил меня указать: "[бокс] так же дорого, как создание любого другого небольшого объекта". Итак, я не хочу преувеличивать влияние производительности. Тем не менее, я намерен вооружить интеллектуальных читателей информацией, которую они должны сделать умный решения, основанные на их индивидуальные обстоятельства.

EDIT: хорошо, поэтому, если вы хотите быть техническим, я снимаю свое предыдущее заявление. От C# ECMA стандарт: "все типы неявно наследуются от класса Object. Невозможно, чтобы какой-либо тип производился от типа значения, и поэтому типы значений неявно запечатаны (§17.1.1.2)."(C# ECMA Standard Page 130) однако... Я понимаю, что суть вопроса OP действительно связана с производительностью и тем, как типы обрабатываются под капотом .Сеть. К этому моменту: типы значений обрабатываются иначе, чем ссылочные типы - и простые типы (int, float и т. д.) сохраняются и действовал эффективно. Когда они рассматриваются как объекты, вы платите дорогую стоимость производительности (как подозревает ОП). Мораль этой истории для меня, и, надеюсь, для кого - то еще, состоит в том, чтобы избегать бокса, что на практике означает, что типы ценностей отличаются от объекта... прими мой ответ, как хочешь.


вы ошибаетесь. Система.Целое число и система.Float не являются подклассами системы.Объект. Это то, что называется "типами значений".

вы можете видеть, что это верно в документации:http://msdn.microsoft.com/en-us/library/system.int32.aspx Что показывает, что Int является "структурой".

в этой статье подробно рассматривается тема:http://msdn.microsoft.com/en-us/library/34yytbws%28v=vs.71%29.aspx

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

в отношении более широкого вопроса: "Почему большинство типов в C# наследуется от системы.Объект", вы обнаружите, что в этом нет ничего уникального. Ява есть Ява.ленг.Объект, Objective-C имеет NSObject и т. д. так далее. Различие между типами значений и ссылочными типами почти универсально. Я не уверен, что мне действительно нужно вдаваться в длинный ответ на это здесь, потому что я думаю, указывая на разницу, и статья о типах значений в C#, уже, вероятно, ответила на ваш вопрос.

чтобы уточнить все остальные вопросы о боксе, так далее.: http://msdn.microsoft.com/en-us/magazine/cc301569.aspx