Подтвердить что ты не робот

"Readonly" (С#) уменьшает использование памяти?

В С#, задает ли поле значение, только что уменьшающее использование памяти?

то есть.

DBRepository _db = new DBRepository();

против

readonly DBRepository _db = new DBRepository();

Просто любопытно. Спасибо.

4b9b3361

Ответ 1

Нет.

Это означает, что вы не можете назначить ему, кроме как в точке объявления или в конструкторе. Вы также не можете передать его как параметр ref или out для метода.

Изменить: на основе приведенного ниже комментария. Следующее поле readonly, потому что вы хотите, чтобы вызывающие абоненты имели прямой доступ для чтения к string.Empty, но вы не хотите, чтобы они устанавливали его на что-то еще.

public sealed class String
{
    public static readonly string Empty = "";
}

Кроме того, иногда, когда у меня есть List<> или Dictionary<> как поле в классе, я объявлю его readonly, чтобы указать, что я хочу работать со своими членами (даже добавление и удаление элементов и т.д.)..), но я никогда не хочу назначать для него другой объект List или Dictionary.

Еще одно редактирование: убедитесь, что вы прочитали об устаревшем поле Path.InvalidPathChars (в разделе примечаний), чтобы показать серьезную проблему, которая может произойти, если вы не понимаете, что readonly есть и нет.

Ответ 2

Нет. readonly и const в основном выполняют одну и ту же цель: предотвратить присвоение значений во время выполнения. Однако они имеют семантически разные виды использования.

readonly versus const

Поле

A const оценивается во время компиляции и может быть инициализировано только при объявлении, а поле readonly оценивается во время выполнения и может быть инициализировано как в конструкторах, так и на сайте объявления.

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

Ответ 3

ДА!

Да? Да! Как? Просто. Поле только для чтения не может получить новое значение, поэтому вы не можете создать второй DBRepository и назначить его этому полю. Если он не доступен для чтения, вы можете написать код, который будет переназначать новое значение в этом поле. И в течение промежутка времени между переназначением и временем сбора сборщика мусора, чтобы очистить старое значение, у вас будет немного больше памяти. Кроме того, если очистка DBRepository имеет утечку памяти, переназначение новых значений в этом поле приведет к утечке памяти.

Ситуация, когда такая утечка памяти может произойти, такова: 1) Вы присваиваете значение _db. 2) Вы присваиваете значение _db другому полю. 3) Вы переназначаете новое значение на _db. На данный момент у вас будет два объекта DBRepository в памяти, потому что старый объект по-прежнему ссылается на другой объект. Таким образом, старый объект не будет освобожден до тех пор, пока второе поле не освободит его.

Но это очень нерешительно и довольно редко. Ответ "Нет" более уместен. Не используйте "ReadOnly" для сохранения памяти, потому что вы будете использовать ее по неправильной причине. Используйте "ReadOnly", чтобы убедиться, что другие не переназначат значение для этого поля. (В принципе, я говорю, что это может уменьшить использование памяти...)

Ответ 4

readonly полезен в том случае, если вы хотите использовать объект в качестве ключа. Этот ключ не должен изменяться, иначе вы не сможете получить доступ к тому, к чему он предоставляет доступ.

Например; 1) с событиями на сайте ASP.NET, вы можете использовать коллекцию Events в элементе управления. В вашем контроле вы бы сохранили поле объекта readonly, чтобы ссылаться на обработчики событий в коллекции. 2) При многопоточности вам может потребоваться синхронизация доступа. Это можно сделать, чтобы объединить оператор блокировки с объектом readonly, на котором можно заблокировать.

Ответ 5

Ответ № написан с точки зрения кодера с хорошей производительностью, который уже знает все трюки и ловушки, например:

  • Нет LINQ в плотных петлях. В самом деле. Никто. Когда-нибудь.
  • Передайте свои перечисления в ints перед сравнением
  • Остерегайтесь структур типа значения
  • 'new' - новый Grue
  • CLRProfiler - ваш друг
  • Другие профилировщики ставят переменное время строительства в странные места.

Ответ Да очень важен для кодера, не осведомленного о подводных камнях дизайна С# или того, кто проглотил "Профилирование зла".

Я инициализирую много (возможно, даже LOT) матриц и массивов в нашем коде. Я заметил, что ленивая инициализация: if (variable == null) //variable = new Переменная()

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

С# позволяет нам очень легко писать ужасно память неэффективного кода. malloc был способом заставить нас думать о (де) распределения. Точно так же readonly заставляет нас думать об этом.

Запустите CLRProfiler, убедитесь сами, сколько спама в памяти вы делаете. Если вы пишете HPC без почти сверхчеловеческой дисциплины, есть вероятность, что вы рассылаете спам и можете читать только можете помочь вам не делать этого.

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