Я использую Structures довольно много в дни VB6 и стараюсь избегать их теперь с .NET. Просто интересно, не считают ли использование структур в 2010 году вместо класса?
Спасибо за помощь.
Я использую Structures довольно много в дни VB6 и стараюсь избегать их теперь с .NET. Просто интересно, не считают ли использование структур в 2010 году вместо класса?
Спасибо за помощь.
Выбор Structure
учитывается вместо того, чтобы быть неотъемлемо "противным". Есть причины, почему структура может быть неприятной; однако есть и причины, по которым Class
может быть противным по-своему...
В основном, когда вы решаете между этими двумя объектно-ориентированными видами контейнеров, вы решаете, как будет использоваться память.
В VB.NET существуют разные семантики, связанные с Structure
и Class
, и они представляют разные шаблоны использования памяти.
Создав Class
, вы создаете ссылочный тип.
Создав Structure
, вы создаете тип значения.
Также есть хорошие видео ресурсы на YouTube, если вы учащийся аудио.
Многие статьи в Интернете, подобные этим статьям MSDN, чтобы научить основам и деталям:
Пример
Структуры существуют, потому что в некоторых сценариях они имеют больше смысла, чем классы. Они особенно полезны для представления небольших абстрактных типов данных, таких как 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);
Считалось довольно плохим использовать что-либо, не понимая последствий.
Структуры типы значений, а не ссылочные типы - и как таковые они ведут себя несколько иначе. Когда вы передаете тип значения, модификации находятся на копии, а не на оригинале. Когда вы присваиваете тип значения справочной системе object
(скажем, в нетривиальном списке), возникает boxing. Убедитесь, что вы прочитали полный эффект выбора одного из них.
Прочитайте this для понимания преимуществ структур против классов и наоборот.
Структура может быть предпочтительной, если:
- У вас есть небольшой объем данных и просто требуется эквивалент UDT (пользовательский тип) предыдущих версий Visual Basic
- Вы выполняете большое количество операций для каждого экземпляра и выполняете ухудшение производительности при управлении кучей.
- Вам не нужно наследовать структуру или специализироваться функциональность среди своих экземпляров
- Вы не вставляете и не распаковываете структуру
- Вы передаете данные, относящиеся к яркости, через управляемую/неуправляемую границу.
Класс предпочтительнее, если:
- Вам нужно использовать наследование и полиморфизм
- Вам нужно инициализировать один или несколько членов во время создания
- Вам нужно предоставить непараметрированный конструктор
- Вам нужна неограниченная поддержка обработки событий.
Чтобы ответить на ваш вопрос напрямую, нет ничего существенного в использовании структуры в VB.NET. Как и при любом дизайнерском решении, вам нужно учитывать последствия этого решения.
Важно, чтобы вы знали о различии между классом и структурой, чтобы вы могли принять обоснованное решение о том, что подходит. Как было сказано Алексом и другими, одно из ключевых различий между структурой и классом состоит в том, что структура считается типом значения, а класс считается ссылочным типом.
В ссылочных типах используется семантика копирования по ссылке, это означает, что когда объект создается или копируется, в стеке выделяется только указатель на фактический объект, фактические данные объекта выделяются в куче.
Напротив, типы значений имеют семантику по порядку, что означает, что каждый раз, когда копируется тип значения (например, структура), весь объект копируется в новое место в стеке /
Для объектов с небольшим количеством данных это не проблема, но если у вас большой объем данных, то использование ссылочного типа, вероятно, будет менее дорогостоящим с точки зрения распределения стека, поскольку только указатель будет скопированы в стек.
Microsoft имеют рекомендации по использованию структур, которые более точно описывают различия между классами и структурами и последствия выбора одного над другим
С поведенческих точек зрения существует три типа "вещей" в .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)
При использовании классов, если требуется объект, который немного отличается от существующего объекта, перед мутацией объекта необходимо учитывать, может ли кто-либо еще захотеть использовать оригинал; если это так, нужно сделать копию, а затем внести необходимые изменения в копию. В структурах нет такого ограничения.
Простым способом представления типов значений является рассмотрение каждой операции присваивания как создания клона оригинала, но в значительно более дешевом виде, чем клонирование типа класса. Если бы кто-то мог клонировать множество объектов так часто, как присваивать ссылки без клонирования, это существенный аргумент в пользу структур.