VB.NET: использует Structures считается противным?

Я использую Structures довольно много в дни VB6 и стараюсь избегать их теперь с .NET. Просто интересно, не считают ли использование структур в 2010 году вместо класса?

Спасибо за помощь.

Ответ 1

Выбор Structure учитывается вместо того, чтобы быть неотъемлемо "противным". Есть причины, почему структура может быть неприятной; однако есть и причины, по которым Class может быть противным по-своему...

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


В VB.NET существуют разные семантики, связанные с Structure и Class, и они представляют разные шаблоны использования памяти.

Создав Class, вы создаете ссылочный тип.

  • подходит для больших данных
  • память содержит ссылку на местоположение объекта в куче (например, концепцию указания на объект), хотя она прозрачно работает с программистом VB.NET, потому что вы находитесь в "управляемом режиме".

Создав Structure, вы создаете тип значения.

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

Также есть хорошие видео ресурсы на YouTube, если вы учащийся аудио.

Многие статьи в Интернете, подобные этим статьям MSDN, чтобы научить основам и деталям:

Пример
alt text

Ответ 2

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

Основная мотивация использования структур заключается в том, чтобы избежать давления ГХ. Поскольку структуры живут inline (в стеке или внутри любого контейнера, в который вы их помещаете), а не в кучу, они обычно приводят к значительно меньшему количеству небольших распределений, что имеет огромное значение, если вам нужно иметь массив из миллиона точек или рациональных.

Ключевой проблемой, которую следует учитывать, является то, что структуры являются типами значений и, следовательно, обычно передаются по значению (очевидным исключением являются параметры ref и out). Это имеет важные последствия. Например:

Point3D[] points = ...;
points[9].Move(0, 0, 5);

Приведенный выше код работает отлично и увеличивает координату z 10-й точки на 5. Однако следующий код:

List<Point3D> points = ...;
points[9].Move(0, 0, 5);

Будет компилироваться и выполняться, но вы обнаружите, что координата z 10-й точки остается неизменной. Это связано с тем, что оператор индекса List возвращает копию точки, и это копия, на которую вы вызываете Move.

Решение довольно простое. Всегда делайте структуры неизменными, отмечая все поля только для чтения. Если вам по-прежнему нужны точки Move, определите + в типе Point3D и используйте назначение:

points[9] = points[9] + new Point3D(0, 0, 5);

Ответ 3

Считалось довольно плохим использовать что-либо, не понимая последствий.

Структуры типы значений, а не ссылочные типы - и как таковые они ведут себя несколько иначе. Когда вы передаете тип значения, модификации находятся на копии, а не на оригинале. Когда вы присваиваете тип значения справочной системе object (скажем, в нетривиальном списке), возникает boxing. Убедитесь, что вы прочитали полный эффект выбора одного из них.

Ответ 4

Прочитайте this для понимания преимуществ структур против классов и наоборот.

Структура может быть предпочтительной, если:

  • У вас есть небольшой объем данных и просто требуется эквивалент UDT   (пользовательский тип) предыдущих версий Visual Basic
  • Вы выполняете большое количество операций для каждого экземпляра и выполняете   ухудшение производительности при управлении кучей.
  • Вам не нужно наследовать структуру или специализироваться   функциональность среди своих экземпляров
  • Вы не вставляете и не распаковываете структуру
  • Вы передаете данные, относящиеся к яркости, через управляемую/неуправляемую границу.

Класс предпочтительнее, если:

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

Ответ 5

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

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

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

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

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

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

Ответ 6

С поведенческих точек зрения существует три типа "вещей" в .net:

  • Переменные ссылочные типы
  • Типы значений, которые могут быть изменены без полной замены
  • Неизменяемые ссылочные и стоимостные типы

Эрик Липпер действительно не любит группу № 2 выше, поскольку .net не очень хорошо справляется с ними, и иногда относится к ним так, как если бы они были в группе №1 или №3. Тем не менее, бывают случаи, когда изменяемые типы значений имеют больше смысла семантически, чем что-либо еще.

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

  Rect2 = Rect1       ' Makes a new Rectangle that just like Rect1
  Rect2.Height = Rect2.Height*2

чем сказать либо

  Rect2 = Rect1.Clone  ' Would be necessary if Rect1 were a class
  Rect2.Height = Rect2.Height*2

или

  Rect2 = New Rectangle(Rect1.Left, Rect1.Top, Rect1.Width, Rect1.Height*2)

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

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