2015-03-12 2 views
3

Я использую, Asp.Net. У меня возникла проблема относительно правильной конструкции структуры readonly в пользовательском кеше, который я создал.Лучший способ создать полный список только для чтенияОпределенный объект

Подробности (резюме):
Мой CacheManager класс (Singleton) использует в качестве параметра, экземпляр существующего MemoryCache класса и обтекает несколько полезных методов, чтобы иметь дело с дополнительным материалом, таких как объект жизненного цикла в моей пользовательский кеш.

, что менеджер имеет дело с простым CachableObject, который принимает три переменные:

  • object
  • DateTime
  • int (длительность)

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

В последнее время я пытался:

  • Возвращенный объект из кэша (т.е. хранится под ключом -MyList)
  • отливают его обратно к списку Complexe объектов
  • переводил содержимое некоторых свойств для каждого объекта комплекса
  • С сохранением вновь переведенного списка объектов в кеше (под другим ключом -MyTranslatedList)

Проблема:
Во время моего тестирования, мне казалось, что оба список хранится в кэше (сыром и переводил один) была отсылая к тому же базовые объекты. Поэтому после перевода эти объекты были фактически переведены в оба списка.
Поскольку у каждого списка есть только ссылки на объекты, это совершенно нормальное поведение и глупая ошибка от меня.

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

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

То, что я пытался до сих пор:
Я попытался сделать object неизменяемые. Это не сработало, как ожидалось.

Поскольку я часто храню список объектов complexe, я нашел метод AsReadOnly, который возвращает IReadOnlyCollection, но хотя это мешает мне изменять список (добавлять, удалять), он не защищает объекты, которые в списке.

Надеюсь, мои объяснения несколько понятны :) Есть ли опрятный способ справиться с такой ситуацией?

+0

Нет, нет никакого способа, чтобы предотвратить кто-то от изменения объекта, если он имеет ссылку на него , Если вы действительно не хотите изменять объекты, вы можете сделать их «ICloneable» или предоставить для них интерфейс только для чтения. – Spo1ler

+0

Вы можете использовать [Неизменяемые коллекции] (https://msdn.microsoft.com/en-us/library/dn769092%28v=vs.111%29.aspx) – Sameer

+0

@Sameer Спасибо за ваш ответ Sameer. До сих пор, из того, что я понял, коллекции Immutable обеспечивают потокобезопасный доступ к списку, который не изменится. Он не гарантирует, что элемент в списке не будет изменен ... Знаете ли вы, что я имею в виду? –

ответ

0

Я хотел бы создать класс, где свойства только для чтения:

class ReadonlyClass 
{ 
    private string p1; 
    private int p2; 

    public ReadonlyClass(string property1, int property2) 
    { 
     p1 = property1; 
     p2 = property2; 
    } 

    public string Property1 
    { 
     get { return p1; } 
    } 

    public int Property2 
    { 
     get { return p2; } 
    } 
} 

Если свойства являются объекты/другие классы, вы должны реализовать функцию клонирования, которая возвращает копию объекта. Функция клонирования для указанного класса будет lõoke так:

public ReadonlyClass clone() 
    { 
     return new ReadonlyClass(p1, p2); 
    } 

С наилучшими пожеланиями Hans Фрезерная ...

+0

Привет, Ханс, Спасибо за ваш ответ. Дело в том, что в моем кеше могут быть какие-то объекты. Он также включает объекты, которые создаются вне моего исходного кода, такие как объекты Entity Framework, возвращаемые из запросов. –

Смежные вопросы