Чем класс отличается от структуры

Чем класс отличается от структуры

Сегодня я решил рассказать о одном из частых вопросах на собеседованиях «чем отличается класс от структуры в C#«.

На самом деле ответить на этот вопрос можно очень коротко. Структура в C# является типом передающимся по значению, класс же является ссылочным типом. По большей части сказать больше нечего. Однако данный ответ врятли внесет какую то ясность людям, которые не понимают что значит передавать по ссылке или передавать по значению. Поэтому давайте рассмотрим данный вопрос подробней на примерах. Предположим что у нас есть «class cA» и struct «sA».
Первое важное отличие ссылочного типа от типа передаваемого по значению это то, что значимый тип не может быть равен null.

Так как структура не может быть равна null то она должна быть инициализирована. При этом инициализация структуры происходит по умолчанию нулевыми значениями. В следствие этого вы не можете создать конструктор по умолчанию для структур. А как следствие не можете инициализировать значения переменных в структурах inline.

Но главным различаем данных двух конструкций является их поведение при присваивании. Это повередение очень легко рассмотреть на примере:

Данный пример очень наглядно демонстрирует различие между передачей значения по ссылки и по значению. Как видно передача по значению подрузомевает создание новой переменной и копирование в нее всех значений. Что в дальнейшем позволяет работать с двумя различными объектами. Передача же по ссылке подрузомевает создание новой ссылки на уже имеющиеся значения.
Если проводить аналогию, например, с Windows, то передача по значению — это копирование ваших файлов, а передача по ссылке — создание ярлыков.

Прежде чем понимать разницу между Class и Struct, мы должны знать несколько базовых понятий, связанных с ними. Без понимания понятий трудно понять различия между ними.

Что такое класс и объект:

Это две важные концепции, связанные с объектно-ориентированным программированием, и они составляют основу для создания функций и данных, передаваемых другим функциям. Для лучшего понимания мы можем соотнести это с реальным примером. Класс можно рассматривать как хранилище, а объектом может быть любой из отдельных специализированных магазинов, таких как продуктовый магазин, канцелярские принадлежности, фрукты и т. Д. Все объекты имеют общие свойства основного класса — магазина — и, в свою очередь, объекты могут иметь свои собственные эксклюзивные свойства, такие как конкретный дизайн, освещение и т. д. Через объекты мы можем фактически использовать класс; они образуют экземпляры класса.

Синтаксис класса

дизайн публичных строк;

Синтаксис объекта

Магазин бакалейных товаров = новый магазин ();

Store Stationery = новый Store ();

Что такое структура?

В состав Struct входят только данные, и поэтому он полезен при формировании индивидуальных требований к данным через объекты Struct. В отличие от класса, он не имеет функций. Вот его синтаксис:

char имя_пользователя [50];

Все магазины могут использовать вход «Struct» с индивидуальными именами и размерами.

Что такое наследование?

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

Теперь, когда мы знакомы с базовыми понятиями, мы можем вникать в фактическую разницу между Class и Struct.

Как они отличаются?

  • Re-юзабилити: Поскольку классы образуют основную структуру, их можно повторно использовать; Структуры, однако, являются отдельными элементами со специфическими свойствами, поэтому их нельзя повторно использовать. Например, класс продуктового магазина можно использовать для любого типа продуктового магазина, но Struct grocery_entrance специфичен только для этого, и нет смысла повторно использовать его в других классах.
  • Видимость: Все функции класса являются общедоступными для своих объектов. Например, у нас есть функция под названием «вещи» в классе «store». Функция «вещи» видна для всех ее объектов, таких как «продуктовый магазин», «хранилище канцелярских товаров» и т. Д. Подобная видимость невозможна с помощью Structs, поскольку данные структуры ограничены самим собой и не видны другим структурам. Чтобы все было ясно, мы можем сказать, что данные «grocery_entrance» не являются общедоступными для всех других магазинов.
  • Pass by Reference & Pass by Value: Pass by Reference отправляет только данные в память, а не фактические данные в функции. Это означает, что всякий раз, когда значение изменяется, это изменение отражается в соответствующих функциях. Передача по значению, в свою очередь, просто отправляет значение функции. В этом случае изменение значения после его отправки не будет отражено в функции. Класс использует pass by reference, а Struct использует значение pass.
  • Наследование: Классы могут быть дополнительно унаследованы для формирования подклассов, но Structs не могут использовать наследование. Например, Class Store предоставляет свои функции подклассическому продуктовому магазину. Но Struct ‘grocery_entrance’ не может наследовать какую-либо функцию. Мы можем сказать, что здесь нет такой концепции, как подструктура.
  • Видимость по умолчанию: Все члены класса сохраняются как частные объекты по умолчанию, тогда как члены Struct по умолчанию сохраняются как общедоступные.
  • Размер пустого класса и структуры: Класс использует размер 1 байт, даже если он пуст, тогда как Struct никогда не использует память, когда она пуста. Это означает, что мы можем сказать, что размер пустой структуры равен 0 байтам.
  • Вывоз мусора: Сбор мусора возможен с помощью классов, поскольку они используют проход по ссылке. Таким образом, проще выполнить очистку в одном месте, где хранятся данные. С другой стороны, сбор мусора невозможен с помощью Struct, поскольку он использует пропуск по значению, и данные разбросаны в разных местах.
  • Управление памятью: Поскольку Class позволяет сборку мусора, управление памятью также эффективно; однако это не так эффективно с Structs.
  • Конструктор: Конструктор обычно инициализирует класс с определенными заданными значениями. Мы можем рассматривать это как нечто, которое было инициализировано значениями. Если новый класс должен быть создан, конструктор вызывается для выделения памяти для этого экземпляра. Мы даже можем передавать значения в качестве аргументов при вызове конструктора. Давайте приступим к нашей реальной дискуссии.Классы допускают конструкторы всех типов, например, с аргументами или без них, тогда как структуры допускают конструкторы с аргументами, т. Е. Параметризованные конструкторы.
  • деструктор: Деструктор вызывается всякий раз, когда нам нужно удалить экземпляр класса. Деструктор, в свою очередь, удаляет этот экземпляр и освобождает память. Класс может использовать деструктор, тогда как Struct не может.
  • Инициализация переменных-членов: В классах мы можем инициализировать переменные-члены напрямую; такая инициализация невозможна с помощью Structs.
  • Создание объекта: Общий синтаксис для создания объектов в классах:
Читайте также:  Изменить дату создания папки program files

Demo obj = new Demo ();

Это означает, что мы должны использовать ключевое слово ‘new’ при создании объектов класса. Это не требуется при создании объектов Structs. Просто взгляните на их синтаксис:

Он отлично работает даже без ключевого слова «новый».

Когда использовать класс и когда использовать Struct?

Поскольку классы более гибки в передаче данных и функций вместе, мы можем пойти на это, когда используемые объекты являются сложными и большими. В нашем примере Mall может использовать класс «store», чтобы лучше выразить систему. Структуры, однако, ограничены меньшими объектами, так как они сравнительно менее эффективны, чем Классы. Поэтому, если вы создаете собственный магазин, Structs — лучший выбор.

Как преобразовать структуру в класс и наоборот?

Возможно, вы слышали термины «бокс» и «распаковка» для преобразования Struct в класс и наоборот. Хотя это эффективные процессы, которые помогают нам в конверсии, их следует рассматривать с осторожностью. Поскольку это напрямую влияет на места памяти, это оказывает огромное влияние на производительность нашей системы. Более того, это влияет на процессы сбора мусора и приводит к общей неэффективности системы. Поэтому используйте эти преобразования только тогда, когда это необходимо.

Давайте рассмотрим вышеупомянутые различия в табличной форме.

S.No Концепции Различия
Учебный класс Struct
1 Повторное удобство Полностью повторное использование Не используется повторно
2 видимость Все функции класса видны его объектам Данные объекта Struct не видны другим объектам одного и того же Struct
3 Pass by Reference & pass by Value Использует Pass by Reference Использует пропуск по значению
4 наследование Функции класса могут быть унаследованы его подклассами; позволяет наследование Никогда не разрешает наследование
5 Видимость по умолчанию Все члены класса закрыты по умолчанию Все члены Struct являются общедоступными по умолчанию
6 Размер при пустом Размер пустого класса равен 1 байт Размер пустой Struct равен 0 байтам
7 Вывоз мусора Поскольку он использует пропуск по ссылке, возможна сборка мусора Поскольку он использует пропуск по значению, сбор мусора невозможен
8 Управление памятью Легкость процесса сбора мусора помогает в эффективном управлении памятью Отсутствие сбора мусора приводит к плохому управлению памятью
9 Конструкторы Позволяет создавать конструкторы всех типов, например, с параметрами или без них Разрешает только параметризованные конструкторы
10 деструкторы Может использовать его Нельзя использовать
11 Инициализация переменных-членов Позволяет прямую инициализацию переменных-членов Не допускает прямой инициализации слов переменных-членов
12 Создание объекта Необходимо использовать ключевое слово «новое» при создании объекта Необязательно использовать ключевое слово «новое» при создании объекта
13 Когда использовать? Лучше для больших и сложных объектов, где требуется наследование Лучше для более мелких и простых объектов, где наследование менее важно.
Читайте также:  Как писать функции в excel

Мы почти покрыли все различия между Class и Struct, и если вы чувствуете, что чего-то не хватает, сообщите нам об этом. Давайте учиться вместе и максимально использовать эти знания!

ru-RU | создано: 10.07.2011 | опубликовано: 10.07.2011 | обновлено: 03.10.2018 | просмотров за всё время: 66084

Мне в последнее время очень часто встречаются программисты, которые не только используют в обычной “программной” жизни структуры (struct), но вообще, ничего не знают об этом объекте. И зачастую, для простоты своей "программной" жизни используют всегда классы (class). В этой статье я бы хотел в очередной раз остановиться на различиях между структурами и классами.

Что такое struсture?

Структуры синтаксически очень похожи на классы, но существует принципиальное отличие, которое заключается в том, что класс – является ссылочным типом (reference type), а структуры – значимый класс (value type). А следовательно, классы всегда создаются в, так называемой, “куче” (heap), а структуры создаются в стеке (stack). Цитата из комментария: "Имхо, главное отличие структур и классов: структуры передаются по значению (то есть копируются), объекты классов — по ссылке. Именно это является существеннейшим различием в их поведении, а не то, где они хранятся. Примечание: структуру тоже можно передать по ссылке, используя модификаторы out и ref."

Ключевой момент статьи: Чем больше Вы будете использовать структуры вместо небольших (наверное, правильнее будет сказать – маленьких) классов, тем менее затратным по ресурсам будет использование памяти. Смею предположить, что не требуется объяснения почему… “куча”, “сборщик мусора”, “неопределенные временные интервалы прохода”, сложность “ручного” управления кучей и сборщиком мусора. Все ключевые моменты уже перечислены.

Так же как и классы, структуры могут иметь поля, методы и конструкторы. Хотя про конструкторы надо поговорить подробнее (будет дальше по теме), ибо это есть очень важное понятие при сравнивании классов и структур.

Структуры всегда с ВамиНе хочется думать, что следующая информация, для Вас сюрпризом. В языке C# примитивные числовые типы int, long, float являются альясами для структур System.Int32, System.Int64 и System.Single соответственно. Эти структуры имеют поля и методы. Вы обычно вызываете методы у переменных данных типов. Например, каждая из перечисленных структур имеет метод ToString. Также у перечисленных структур есть статичные поля, например, Int32.MaxValue или Int32.MinValue. Получается, что Вы уже в повседневной "программной" жизни используете структуры, а значит знакомы с ними.

Таблица классов и структур в Microsoft. NET Framework

В таблице указаны альясы и соответствующие им типы, а также дана информация о представляющем типе (структура или класс).

Keyword Type equivalent Class or structure
bool System.Boolean Structure
byte System.Byte Structure
decimal System.Decimal Structure
double System.Double Structure
float System.Single Structure
int System.Int32 Structure
long System.Int64 Structure
object System.Object Class
sbyte System.SByte Structure
short System.Int16 Structure
string System.String Class
uint System.UInt32 Structure
ulong System.UInt64 Structure
ushort System.UInt16 Structure
Читайте также:  Как сделать нано симку в домашних условиях

Объявление структур

Для объявления структуры используется зарезервированное слово struct, следом наименование структуры и фигурные скобки:

В отличие от классов, использование публичных полей в структурах в большинстве случаев не рекомендуется, потому что не существует способа контролирования значений в них. Например, кто-либо может установит значение минут или секунд более 60. Более правильный вариант в данном случае — использовать свойства, а в конструкторе осуществить проверку:

Кстати, …По умолчанию, Вы не можете использовать некоторые общие операторы в Ваших структурах. Например, Вы не можете использовать оператор сравнения (==) и противоположные ему (!=) на своих структурах. Однако, Вы можете явно объявить и реализовать операторы для своих структур.

И в чем же разница между структурами и классами

Давайте рассмотрим пример, в котором уже заложена ошибка:

Причина возникновении ошибки в том, что Вы не можете использовать конструктор по умолчанию (без параметров) для структуры, потому что компилятор всегда генерирует его сам. Что же касается класса, то компилятор создает конструктор по умолчанию, только в том случае, если Вы его не создали. Сгенерированный конструктор для структуры всегда устанавливает поля в , false или null – как и для классов. Поэтому Вы можете быть уверенными в том, что созданная структура всегда будет вести себя “адекватно” в соответствии со значениями по умолчанию в используемых типах. Если Вы не хотите использовать значения по умолчанию, Вы можете инициализировать поля своими значениями в конструкторе с параметрами для инициализации. Однако, если в этом конструкторе не будет инициализировано какое-нибудь значение, компилятор не будет его инициализировать за Вас и покажет ошибку.

Первое правило Структуры: Всегда все переменные должны быть инициализированы!

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

Второе правило Структуры: Нельзя инициализировать переменные в месте их объявления!

Данная таблица в некотором роде подытоживает всё вышесказанное и отображает основные отличия между классами и структурами.

Вопрос Структура Класс
И какого же типа экземпляр объекта? Структура значимый (value) тип Класс ссылочный (reference) тип
А где “живут” экземпляры этих объектов? Экземпляры структуры называют значениями и “живут” они в стеке (stack). Экземпляры классов называют объектами и “живут” они в куче (heap).
Можно ли создать конструктор по умолчанию? Нет Да
Если создается свой конструктор будет ли компилятор генерировать конструктор по умолчанию? Да Нет
Если в своём конструкторе не будут инициализированы некоторые поля, будут ли они автоматически инициализированы компилятором? Нет Да
Разрешается ли инициализировать переменные в месте их объявления? Нет Да

Использование структур как переменных

После того как Вы создали структуры, Вы можете использовать ее также как классы и другие типы. Например, создав структуру Time, я могу использовать ее в классе:

Вы можете создавать nullable версию переменной типа структуры использую модификатор “?” и потом присвоить ей значение null:

Time? currentTime = null;

Инициализация структур

В статье я не раз говорил, что поля структуры могут быть инициализированы при использования конструктора, причем не важно какого “собственного” или “по умолчанию”. К особенностям структур можно отнести еще и тот факт, что вследствие того, что структуры являются значимым типом, то можно создать структуру без использования конструктора, например:

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

Заключение

Используйте структуры, это признак хорошего тона в программировании на C# и да прибудет с Вами сила… структур. Цитата из комментария: "С заключением тоже не согласен. Многие маститые западные авторы наоборот рекомендуют как можно меньше использовать структуры, предпочитая классы. Хотя, конечно, молиться на них и их мнение не стоит, лучше думать своей головой."

Ссылка на основную публикацию
Adblock detector