MSDN говорит, что вы должны использовать структуры, когда вам нужны легкие объекты. Существуют ли другие сценарии, когда структура предпочтительнее класса?
Некоторые люди могли забыть, что:
- Структуры могут иметь методы.
- структуры не могут быть унаследованы.
Я понимаю технические различия между структурами и классами, я просто не понимаю, когда использовать структуру.
Ответы:
У MSDN есть ответ: Выбор между классами и структурами .
По сути, эта страница дает вам контрольный список из 4 пунктов и говорит, что вы должны использовать класс, если ваш тип не соответствует всем критериям.
источник
ref
параметры всякий раз, когда это целесообразно. Передача структуры с 4000 полями в качестве параметра ref методу, который меняет его, будет дешевле, чем передача структуры с 4 полями по значению методу, который возвращает измененную версию.Я удивлен, что я не читал ни в одном из предыдущих ответов, что я считаю наиболее важным аспектом:
Я использую структуры, когда хочу тип без идентификатора. Например, 3D-точка:
Если у вас есть два экземпляра этой структуры, вам все равно, являются ли они одним фрагментом данных в памяти или двумя. Вы просто заботитесь о ценности, которую они имеют.
источник
return false
это то, что должно было быть там, исправляя сейчас.У Билла Вагнера есть глава об этом в его книге «Эффективный с #» ( http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660 ). В заключение он использует следующий принцип:
источник
Используйте структуру, когда вы хотите семантику типа значения вместо ссылочного типа. Структуры копируются по значению, поэтому будьте осторожны!
Также смотрите предыдущие вопросы, например
В чем разница между структурой и классом в .NET?
источник
Я бы использовал структуры, когда:
объект должен быть только для чтения (каждый раз, когда вы передаете / присваиваете структуру, он копируется). Объекты только для чтения хороши, когда дело доходит до многопоточной обработки, поскольку в большинстве случаев они не требуют блокировки.
объект маленький и недолговечный. В таком случае есть хороший шанс, что объект будет размещен в стеке, что гораздо эффективнее, чем поместить его в управляемую кучу. Более того, память, выделенная объектом, будет освобождена, как только он выйдет за пределы своей области видимости. Другими словами, это меньше работы для сборщика мусора, а память используется более эффективно.
источник
Используйте класс, если:
Используйте структуру, если:
источник
Я всегда использовал структуру, когда хотел сгруппировать несколько значений для передачи данных обратно из вызова метода, но мне не нужно будет использовать его для чего-либо после прочтения этих значений. Так же, как способ держать вещи в чистоте. Я склонен рассматривать вещи в структуре как «одноразовые», а вещи в классе - как более полезные и «функциональные»
источник
Если сущность будет неизменной, вопрос о том, использовать ли структуру или класс, обычно будет связан с производительностью, а не с семантикой. В 32/64-битной системе для ссылок на классы требуется 4/8 байтов для хранения, независимо от объема информации в классе; копирование ссылки на класс потребует копирования 4/8 байтов. С другой стороны, каждый отдельныйЭкземпляр класса будет иметь 8/16 байтов служебной информации в дополнение к информации, которую он содержит, и стоимости памяти для ссылок на него. Предположим, кто-то хочет массив из 500 сущностей, каждая из которых содержит четыре 32-битных целых числа. Если объект является структурным типом, массиву потребуется 8000 байтов независимо от того, все ли 500 объектов идентичны, различны или где-то между ними. Если сущность является типом класса, массив из 500 ссылок займет 4000 байтов. Если все эти ссылки указывают на разные объекты, объектам потребуются дополнительные 24 байта каждый (12 000 байтов на все 500), всего 16 000 байтов - вдвое больше, чем стоимость хранения типа структуры. С другой стороны, из кода, который создал один экземпляр объекта, а затем скопировал ссылку на все 500 слотов массива, общая стоимость составила бы 24 байта для этого экземпляра и 4, 000 для массива - всего 4024 байта. Основная экономия. Немногие ситуации сработают так же хорошо, как и последняя, но в некоторых случаях может оказаться возможным скопировать некоторые ссылки на достаточное количество слотов массива, чтобы сделать такое совместное использование полезным.
Если предполагается, что сущность является изменчивой, вопрос о том, использовать ли класс или структуру, в некотором смысле проще. Предположим, что «Thing» - это либо структура, либо класс с целочисленным полем с именем x, и каждый выполняет следующий код:
Желает ли последнее утверждение повлиять на t1.x?
Если Thing является типом класса, t1 и t2 будут эквивалентны, то есть t1.x и t2.x также будут эквивалентны. Таким образом, второе утверждение повлияет на t1.x. Если Thing является структурным типом, t1 и t2 будут разными экземплярами, то есть t1.x и t2.x будут ссылаться на разные целые числа. Таким образом, второе утверждение не повлияет на t1.x.
Изменчивые структуры и изменяемые классы имеют принципиально различное поведение, хотя .net имеет некоторые особенности в обработке структурных мутаций. Если кто-то хочет поведение типа значения (имеется в виду, что «t2 = t1» будет копировать данные из t1 в t2, оставляя t1 и t2 как отдельные экземпляры), и если можно жить со странностями в обработке типов значений в .net, используйте структура. Если кто-то хочет семантику типа значения, но причуды .net могут привести к нарушению семантики типа значения в приложении, используйте класс и бормотайте.
источник
Кроме того, превосходные ответы выше:
Структуры являются типами значений.
Они никогда не могут быть установлены в Ничто .
Установка структуры = Ничего, установит для всех типов значений значения по умолчанию.
источник
когда вам действительно не нужно поведение, но вам нужно больше структуры, чем простой массив или словарь.
Последующие действия Вот как я думаю о структурах в целом. Я знаю, что у них могут быть методы, но мне нравится сохранять это общее умственное различие.
источник
Как сказал @Simon, структуры предоставляют семантику «тип значения», поэтому, если вам нужно поведение, подобное встроенному типу данных, используйте struct. Поскольку структуры передаются посредством копирования, вы должны убедиться, что они имеют небольшой размер, около 16 байт.
источник
Это старая тема, но мы хотели предоставить простой тест производительности.
Я создал два файла .cs:
и
Выполнить тест:
Полученные результаты:
источник
Хм ...
Я бы не использовал сборку мусора в качестве аргумента за / против использования структур против классов. Управляемая куча работает во многом как стек - создание объекта просто помещает его на вершину кучи, что почти так же быстро, как и размещение в стеке. Кроме того, если объект недолговечен и не выдерживает цикл GC, освобождение происходит бесплатно, поскольку GC работает только с памятью, которая все еще доступна. (Поищите в MSDN, есть серия статей по управлению памятью .NET, мне просто лень копаться в них).
Большую часть времени, когда я использую структуру, я начинаю пинать себя за это, потому что позже я обнаружу, что наличие ссылочной семантики сделало бы вещи немного проще.
В любом случае, эти четыре пункта в статье MSDN, опубликованной выше, кажутся хорошим руководством.
источник
class MutableHolder<T> { public T Value; MutableHolder(T value) {Value = value;} }
, и тогда aMutableHolder<T>
будет объектом с изменяемой семантикой класса (это работает так же хорошо, еслиT
это структура или тип неизменяемого класса).Структуры находятся в стеке, а не в куче, поэтому они являются потокобезопасными, и их следует использовать при реализации шаблона передаваемых объектов, вы никогда не захотите использовать объекты в куче, они являются энергозависимыми, в этом случае вы хотите использовать стек вызовов, это основной случай использования структуры. Я удивлен всеми ответами здесь,
источник
Я думаю, что лучший ответ - просто использовать struct, когда вам нужен набор свойств, класс, когда это набор свойств и поведений.
источник