Хранение ссылочных типов в Struct - PullRequest
4 голосов
/ 16 февраля 2012

Скажем, у меня была очень простая структура в c #

   public struct foo{
   public  int a{get;set;}
   public  int b{get;set;}
   public  int c{get;set;}
   public  int d{get;set;}
   public  string hello {get;set;}
   }

Я так понимаю, вышеприведенное более "эффективно", чем использование class?

В какой момент, если япродолжал добавлять строковые свойства, не пора ли будет преобразовать структуру в класс?

Редактировать: Я планировал передать эту структуру вокруг приложения, ориентированного на GDI.Я всегда предполагал, что структуры более производительны при работе с типами значений.

Ответы [ 6 ]

27 голосов
/ 16 февраля 2012

Я так понимаю, вышеописанное более "эффективно", чем использование класса?

Абсолютно нет. Это ужасная структура . Структуры должны быть небольшими; скажем, в четыре раза больше, чем ссылка; Ваша структура имеет размер пяти ссылок на 32-битной машине. Структуры должны представлять значения ; это, кажется, не представляет никакой ценности. Структуры должны быть неизменными ; это биток изменчивости.

В какой момент, если я продолжу добавлять строковые свойства, пора ли преобразовать структуру в класс?

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

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

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

В любом случае, вы узнаете, что что-то более эффективно, , попробуйте оба способа и сравните его производительность с вашими целями производительности . Использование науки . Установить цель и измерить ее. Использование структур «потому что я предполагаю, что они более эффективны» - это принятие технических решений на основе слухов. Измерьте , и тогда вы поймете, что более эффективно.

4 голосов
/ 16 февраля 2012

Если вам нужны расширенные возможности, которые предлагает класс, такие как наследование, переключитесь.Если нет, структура может быть немного «легче», но если вы не предвидите некоторые проблемы с производительностью, такие как сборка мусора внутри замкнутого цикла с большим количеством итераций, необходимость передавать структуры с ref всякий раз, когда вы хотитеметод внесения изменений и т. д. может создать ненужную работу.(Хотя в этом примере уничтожение структуры, которая имеет свойства ссылочного типа, также вызывает GC).

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

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

Для ЭрикаОтличная заметка Липперта о сборке мусора, структурах и классах см. Его ответ на этот вопрос .

1 голос
/ 16 февраля 2012

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

Я ДУМАЮ Однажды я прочитал, что структуры отлично подходят для кратковременного множества объектов, но я могу ошибаться.

1 голос
/ 16 февраля 2012

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

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

0 голосов
/ 17 февраля 2012

Если кто-то скажет:

  foo x[100];
  foo[1] = foo[2];
  foo[1].a += 5;

, должно ли последнее утверждение повлиять на foo[2].a?Если foo является структурным типом, он не будет;если это тип класса, он будет.

Вопреки тому, что говорит г-н Липперт, ваш тип может быть просто отличным в виде структуры, с несколькими оговорками:

  1. Структуры должнывыставлять их поля напрямую, а не через свойства, если только в свойствах не будет какой-то нетривиальной логики.
  2. Передача по структурам значений, длина которых превышает 16 байт, немного медленнее, чем передача по более мелким, поскольку .net имеет специальную обработку для небольших структур.Передача по ссылке не зависит от размера структуры.
  3. Изменяемые структуры, которые содержат изменяемые ссылочные типы, часто демонстрируют семантику, которая является странным пересечением между изменяемой семантикой значений и изменяемой ссылочной семантикой.Однако это не проблема для структур, которые содержат неизменяемые ссылочные типы, такие как `string`.
  4. Свойства типа структуры часто являются болью для работы.Свойства справочных типов, доступные только для чтения, иногда проще работать, но замена типа структуры, который будет содержать 20 байтов данных, классом, который также содержит 20 байтов данных, может почти удвоить требования к хранилищу в 32-битных системах, илиболее чем вдвое их в 64-битных системах.

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

0 голосов
/ 16 февраля 2012

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

К вашему сведению: Класс (компьютерное программирование)

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