В чем разница между структурой и классом в .NET? - PullRequest
604 голосов
/ 16 августа 2008

В чем разница между структурой и классом в .NET?

Ответы [ 18 ]

955 голосов
/ 16 августа 2008

В .NET есть две категории типов: ссылочные типы и типы значений .

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

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

Переменная, содержащая тип значения , содержит полное значение типа значения . Для структуры это означает, что переменная содержит всю структуру со всеми ее полями.

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

Это имеет одно преимущество, для начала:

  • типы значений всегда содержит значение
  • ссылочные типы могут содержать null -референцию, что означает, что в данный момент они вообще ни на что не ссылаются

Внутренне, ссылочный тип s реализован в виде указателей, и зная это, и зная, как работает присвоение переменной, существуют другие поведенческие паттерны:

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

Когда вы объявляете переменные или поля, вот как отличаются два типа:

  • переменная: тип значения живет в стеке, ссылочный тип живет в стеке как указатель на где-то в куче памяти, где живет реальная память (хотя обратите внимание Эрик Серия статей Липпертса: Стек - это деталь реализации .)
  • class / struct-field: тип значения полностью живет внутри типа, ссылочный тип живет внутри типа как указатель на место в кучной памяти, где живет реальная память.
178 голосов
/ 05 октября 2008

Краткое резюме каждого:

Только классы:

  • Может поддерживать наследование
  • являются ссылочными (указательными) типами
  • Ссылка может быть нулевой
  • Издержки памяти на новый экземпляр

Только структуры:

  • Не поддерживается наследование
  • Типы значений
  • Передаются по значению (как целые числа)
  • Не может иметь нулевую ссылку (если не используется Nullable)
  • Не использовать служебную память для каждого нового экземпляра - если только он не упакован

Классы и структуры:

  • Составные типы данных, которые обычно используются, чтобы содержать несколько переменных, которые имеют некоторые логические отношения
  • Может содержать методы и события
  • Может поддерживать интерфейсы
32 голосов
/ 16 августа 2008

В .NET объявления структуры и класса различают ссылочные типы и типы значений.

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

Когда вы передаете тип значения, каждый является копией. Весь код работает на собственной копии.

Это можно показать на примере:

struct MyStruct 
{
    string MyProperty { get; set; }
}

void ChangeMyStruct(MyStruct input) 
{ 
   input.MyProperty = "new value";
}

...

// Create value type
MyStruct testStruct = new MyStruct { MyProperty = "initial value" }; 

ChangeMyStruct(testStruct);

// Value of testStruct.MyProperty is still "initial value"
// - the method changed a new copy of the structure.

Для класса это было бы иначе

class MyClass 
{
    string MyProperty { get; set; }
}

void ChangeMyClass(MyClass input) 
{ 
   input.MyProperty = "new value";
}

...

// Create reference type
MyClass testClass = new MyClass { MyProperty = "initial value" };

ChangeMyClass(testClass);

// Value of testClass.MyProperty is now "new value" 
// - the method changed the instance passed.

Классы могут быть ничем - ссылка может указывать на ноль.

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

18 голосов
/ 14 мая 2017

От Microsoft Выбор между классом и структурой ...

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

РАССМОТРИТЕ структуру вместо класса:

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

X ИЗБЕГАЙТЕ struct , если тип не имеет все следующих Характеристики:

  • Логически представляет одно значение, подобное примитивным типам (int, double и т. Д.).
  • Размер экземпляра не превышает 16 байт.
  • Он неизменен. (не может быть изменено)
  • Это не должно быть часто в штучной упаковке.
18 голосов
/ 14 июня 2012

В дополнение ко всем различиям, описанным в других ответах:

  1. Структуры не могут иметь явного конструктора без параметров , тогда как класс может
  2. Структуры не могут иметь деструкторов , тогда как класс может
  3. Структуры не могут наследовать от другой структуры или класса, тогда как класс может наследовать от другого класса. (И структуры, и классы могут быть реализованы из интерфейса.)

Если вы после видео, объясняющего все различия, вы можете проверить Часть 29 - Руководство по C # - Разница между классами и структурами в C # .

14 голосов
/ 05 января 2018

Разница между структурами и классами:

  • Структуры имеют тип значения , тогда как Классы являются ссылочным типом .
  • Структуры хранятся в стеке , тогда как Классы хранятся в куча .
  • Типы значений хранят свои значения в памяти, где они объявлены, но ссылочный тип содержит ссылку на объектную память.
  • Типы значений уничтожаются немедленно после потери области, тогда как ссылочный тип только для переменной destroy после потери области. впоследствии объект уничтожается сборщиком мусора.
  • Когда вы копируете структуру в другую структуру, новая копия этой структуры создается изменение одной структуры не повлияет на значение другая структура.
  • Когда вы копируете класс в другой класс, он копирует только ссылочная переменная.
  • Обе ссылочные переменные указывают на один и тот же объект в куче. Изменение одной переменной повлияет на другую ссылочную переменную.
  • Структуры не могут иметь деструкторов , но классы могут иметь деструкторы.
  • Структуры не могут иметь явных конструкторов без параметров , тогда как a структуры класса can не поддерживают наследование, но классы поддерживают. И то и другое поддержка наследования от интерфейса.
  • Конструкции герметичного типа .
14 голосов
/ 16 августа 2008

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

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

Различие улучшено именами C ++ / CLI: "ref class" - это класс, который описан первым, "value class" - это класс, как описано вторым. Ключевые слова "класс" и "структура", используемые в C #, просто должны быть изучены.

6 голосов
/ 02 августа 2017

Чтобы завершить его, есть еще одно отличие при использовании метода Equals, который наследуется всеми классами и структурами.

Допустим, у нас есть класс и структура:

class A{
  public int a, b;
}
struct B{
  public int a, b;
}

и в методе Main у нас есть 4 объекта.

static void Main{
  A c1 = new A(), c2 = new A();
  c1.a = c1.b = c2.a = c2.b = 1;
  B s1 = new B(), s2 = new B();
  s1.a = s1.b = s2.a = s2.b = 1;
}

Тогда:

s1.Equals(s2) // true
s1.Equals(c1) // false
c1.Equals(c2) // false
c1 == c2 // false

Итак, , структуры подходят для числовых объектов, таких как точки (сохраните координаты x и y). И занятия подходят для других. Даже если 2 человека имеют одинаковое имя, рост, вес ... они все равно 2 человека.

6 голосов
/ 06 ноября 2009

Структура против класса

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

Структура не поддерживает наследование и полиморфизм, но класс поддерживает оба.

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

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

5 голосов
/ 25 августа 2015

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

  • Со структурой память выделяется внутри содержащего класса для хранения данных.
  • С классом содержащий класс просто будет содержать указатель на новый класс в другой области памяти.

Это также верно для массивов, поэтому массив структур в памяти выглядит следующим образом

[struct][struct][struct][struct][struct][struct][struct][struct]

Где как массив классов выглядит так

[pointer][pointer][pointer][pointer][pointer][pointer][pointer][pointer]

Фактические значения, которые вас интересуют, хранятся не в массиве, а в другом месте в памяти.

Для подавляющего большинства приложений это различие на самом деле не имеет значения, однако в высокопроизводительном коде это повлияет на локальность данных в памяти и окажет большое влияние на производительность кэша ЦП. Использование классов, когда вы могли / должны были использовать структуры, значительно увеличит количество кеш-пропусков в процессоре.

Самым медленным, что делает современный ЦП, является не обработка чисел, а выборка данных из памяти, а попадание в кэш L1 во много раз быстрее, чем чтение данных из ОЗУ.

...