Я использую, Asp.Net
. У меня возникла проблема относительно правильной конструкции структуры readonly
в пользовательском кеше, который я создал.Лучший способ создать полный список только для чтенияОпределенный объект
Подробности (резюме):
Мой CacheManager класс (Singleton) использует в качестве параметра, экземпляр существующего MemoryCache
класса и обтекает несколько полезных методов, чтобы иметь дело с дополнительным материалом, таких как объект жизненного цикла в моей пользовательский кеш.
, что менеджер имеет дело с простым CachableObject
, который принимает три переменные:
object
DateTime
int
(длительность)
В общем, мой пользовательский кэш-менеджер хранит objects
в течение ограниченного периода времени, чтобы защитить мою базу данных от частых больших запросов.
В последнее время я пытался:
- Возвращенный объект из кэша (т.е. хранится под ключом
-MyList
) - отливают его обратно к списку Complexe объектов
- переводил содержимое некоторых свойств для каждого объекта комплекса
- С сохранением вновь переведенного списка объектов в кеше (под другим ключом
-MyTranslatedList
)
Проблема:
Во время моего тестирования, мне казалось, что оба список хранится в кэше (сыром и переводил один) была отсылая к тому же базовые объекты. Поэтому после перевода эти объекты были фактически переведены в оба списка.
Поскольку у каждого списка есть только ссылки на объекты, это совершенно нормальное поведение и глупая ошибка от меня.
Вопрос:
Как вы можете легко догадаться теперь, я хотел бы, чтобы защитить себя и других пользователей моего одноточечного для такого рода ошибок.
Я хотел бы вставить (или сохранить или получить) любой объект (или список объектов комплекса), чтобы они не могли быть изменены кем-либо, получающим их через кеш. Я хотел бы, чтобы данные в моем кеше были только для чтения (и глубоко readonly), чтобы избежать такой проблемы. Я хочу, чтобы кто-нибудь имел, чтобы создать глубокую копию (или даже лучше, до получить один), прежде чем использовать данные, хранящиеся в кеше.
То, что я пытался до сих пор:
Я попытался сделать object
неизменяемые. Это не сработало, как ожидалось.
Поскольку я часто храню список объектов complexe, я нашел метод AsReadOnly, который возвращает IReadOnlyCollection
, но хотя это мешает мне изменять список (добавлять, удалять), он не защищает объекты, которые в списке.
Надеюсь, мои объяснения несколько понятны :) Есть ли опрятный способ справиться с такой ситуацией?
Нет, нет никакого способа, чтобы предотвратить кто-то от изменения объекта, если он имеет ссылку на него , Если вы действительно не хотите изменять объекты, вы можете сделать их «ICloneable» или предоставить для них интерфейс только для чтения. – Spo1ler
Вы можете использовать [Неизменяемые коллекции] (https://msdn.microsoft.com/en-us/library/dn769092%28v=vs.111%29.aspx) – Sameer
@Sameer Спасибо за ваш ответ Sameer. До сих пор, из того, что я понял, коллекции Immutable обеспечивают потокобезопасный доступ к списку, который не изменится. Он не гарантирует, что элемент в списке не будет изменен ... Знаете ли вы, что я имею в виду? –