Что такое класс значений и что такое ссылочный класс в C #?

Какое определение для value class и reference class в C #?

Чем это отличается от value type и reference type?

Я задаю этот вопрос, потому что прочитал об этом в наборе для самостоятельного обучения MCTS (экзамен 70-536). Глава 1, Урок 1, Обзор Урока 4:

Вам нужно создать простой класс или структуру, содержащую только типы значений. Вы должны создать класс или структуру так, чтобы они работали как можно более эффективно. Вы должны иметь возможность передать класс или структуру процедуре, не беспокоясь о том, что процедура ее изменит. Что из следующего вам следует создать?

Эталонный класс

B справочная структура

Класс ценности C

Структура значения D

Правильный ответ: D

A Неправильно: вы можете создать эталонный класс; однако его можно изменить при передаче в процедуру.

B Неправильно: вы не можете создать ссылочную структуру.

C Неправильно: вы могли создать класс значений; однако конструкции имеют тенденцию быть более эффективными.

D Верно: структуры ценностей обычно наиболее эффективны.


person Bastien Vandamme    schedule 02.11.2009    source источник
comment
Перед тем, как вы отредактировали его вопрос, он сказал «Класс значений» и «Контрольный класс», а не «тип». Он мог ссылаться на что-то вроде этого: icsi.berkeley.edu/ ~ sather / Documentation / EclecticTutorial /, где говорится: На фундаментальном уровне: классы значений определяют объекты, которые после создания никогда не меняют своего значения. Переменная типа значения может быть изменена только путем повторного присвоения этой переменной. Когда мы хотим изменить только некоторую часть класса значений (скажем, один атрибут), мы вынуждены переназначить весь объект ... Кто знает, без ссылки на статью.   -  person Jason Down    schedule 02.11.2009
comment
Я не редактировал вопрос. Кто-то сделал это за меня. Это плохое издание. Я действительно имею в виду значение КЛАСС и эталонный КЛАСС.   -  person Bastien Vandamme    schedule 02.11.2009
comment
Да, я понимаю, что ваш вопрос редактировал Джордж Стокер. Я просто указал на то, что вы могли иметь в виду именно то, что напечатали. Похоже, вы только что это разъяснили.   -  person Jason Down    schedule 02.11.2009
comment
Я знаю, что такое значение или ссылочный тип, но я не знаю, что такое значение или ссылочный класс.   -  person Bastien Vandamme    schedule 02.11.2009
comment
Обновил вопрос. Учитывая, что я никогда не слышал о «классе значений» или «эталонном классе» применительно к C #, я был почти уверен, что OP допустил ошибку при публикации. ОП: Пожалуйста, включите ссылку на то, что вы читаете; в противном случае это будет восприниматься как опечатка.   -  person George Stocker    schedule 02.11.2009
comment
@ Джейсон Даун: Но в C # этого не существует как «класс значений» или «эталонный класс».   -  person George Stocker    schedule 02.11.2009
comment
@ Джордж: Я знаю, поэтому я только что оставил комментарий. Термины Value Class и Reference Class действительно существуют, поэтому он мог иметь в виду то, что сказал. Но, как вы сказали, он никогда не публиковал статью, на которую ссылался, поэтому без этого мы не можем быть уверены в том, о чем он говорит. Я, например, никогда не слышал об этих терминах до сегодняшнего дня, не говоря уже о C #.   -  person Jason Down    schedule 02.11.2009
comment
Этот документ представляет собой набор для самостоятельного обучения MCTS (экзамен 70-536). Глава 1. Урок 1: Использование типов значений. Вопрос для повторения урока и исправление № 4. Я редактировал вопрос.   -  person Bastien Vandamme    schedule 02.11.2009


Ответы (7)


Типы значений передаются по значению, а ссылочные типы передаются по ссылке.

Изменить: классы значений / ссылок
В C # нет понятия «класс значений» или «эталонный класс», поэтому спрашивать о его определении нецелесообразно.

person Joren    schedule 02.11.2009
comment
Я добавил ссылку на документ - person Bastien Vandamme; 02.11.2009
comment
Ссылочные типы передаются по значению, но передается ссылка. Это тонкое, но важное различие. - person Wedge; 02.11.2009
comment
Я понимаю вашу точку зрения. Переменные с типом значения напрямую содержат данные, которые передаются по значению. Переменные со ссылочным типом содержат ссылку на данные, ссылка на которые также передается по значению. Если вы используете ref или out, то переменные передаются по ссылке. - person Joren; 02.11.2009
comment
Строго говоря, да, классов значений нет. Но есть неизменяемые ссылочные типы - например, System.String. Они ведут себя как типы значений (за исключением того, что по умолчанию допускают значение NULL). Так что их можно было назвать классами значений. - person Paul Groke; 13.12.2013

Возможно, вы думаете о C ++ / CLI, который, в отличие от C #, позволяет пользователю объявлять «класс значений» или «класс ссылок». В C # любой класс, который вы объявляете, будет неявно ссылочным классом - только встроенные типы, структуры и перечисления имеют семантику значений. Чтобы прочитать о классе значений в C ++ / CLI, посмотрите здесь: http://www.ddj.com/cpp/184401955

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

Чтобы преобразовать класс значений в ссылочный класс (таким образом, поместив его в кучу со сборкой мусора), вы можете «упаковать» его.

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

Если нет, то, вероятно, это класс ценности.

Однако в C # классы значений объявлены как «структуры».

person Drew Hoskins    schedule 02.11.2009

См. обзор по этой теме, но серьезно перейдите по ссылкам msnd и прочтите полную его главу о системе общих типов. (Вы также могли задать вопрос в комментарии к первому вопросу)

person Julien Roncaglia    schedule 02.11.2009

Типы значений хранят фактические данные, а ссылочные типы хранят ссылки на данные. Ссылочные типы динамически хранятся в куче, а типы значений хранятся в стеке.

Типы значений: http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx Типы справочных материалов: http://msdn.microsoft.com/en-us/library/490f96s2.aspx

person jtruelove    schedule 02.11.2009
comment
Не точный. Типы значений, которые являются полями классов, хранятся в куче среди остальной части состояния объекта. - person zvolkov; 02.11.2009
comment
comment
да, мое объяснение было слишком упрощенным - person jtruelove; 03.11.2009

Когда вы ссылаетесь на тип значения (то есть используя его имя), вы говорите о том месте в памяти, где находятся данные. Таким образом, типы значений не могут быть нулевыми, потому что в ячейке памяти нет способа сказать: «Я ничего не представляю». По умолчанию вы передаете типы значений по значению (то есть объект, который вы передаете методам, не изменяется в результате выполнения метода).

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

person Lucas Wilson-Richter    schedule 02.11.2009

Ссылочные типы передаются методам по ссылке, а типы значений - по значению; в последнем случае метод получает копию переменной, а в первом - ссылку на исходные данные. Если вы измените свою копию, оригинал не изменится. Если вы изменяете исходные данные, на которые имеется ссылка, данные изменяются везде, где изменяется ссылка на данные. Если программа, аналогичная вашей программе C #, была создана на C, обычно ссылочные типы были бы подобны данным, использующим указатели, а типы значений были бы обычными данными в стеке.

Числовые типы, char, дата, перечисления и структуры - все это типы значений. Строки, массивы, делегаты и классы (то есть большинство вещей на самом деле) являются ссылочными типами.

person Mike Graham    schedule 02.11.2009

Если я правильно понимаю, вы можете создать «класс значений» или неизменяемый класс с помощью readonly переменных-членов, инициализированных через конструктор. После создания они не могут быть изменены.

person Ryan Emerle    schedule 02.11.2009