Как часть моего приложения, я поддерживаю кэш, который структурирован, как показано ниже,
class Container
{
List<ExecEnv> ExecEnvList;
List<ControlMod> ToBeProcessedControlModList;
// Other Properties goes here
// Other properties can be either simple type or List of other objects etc..,
.....
}
class ExecEnv
{
ObservableCollection<ContMod> ExistingContModList;
ObservableCollection<ContMod> NewContModList;
// Other Properties goes here
// Other properties can be either simple type or List of other objects etc..,
}
class ContMod
{
// Lot of properties, It will be either simple type, list or dictionary
}
Кэш-это словарь контейнера,
Dictionary<int,Container> IDToContainerList;
Изначально NewContModList пуст внутри контейнера. Бизнес-логика c будет обрабатывать каждый Контейнер и распространять ToBeProcessedControlModList среди всех ExecEnvto. Я не хочу обновлять этот NewContModList в Cache. Этот NewContModList должен обновляться до ExecEnv всякий раз, когда клиент запрашивает его.
Поэтому я поддерживаю еще одну карту, в которой ключ ExectionEnv является ключом, а список идентификатора newControlMod - значением
Dictionary<int,List<int>> ExecEnvIDToNewContModList;
Клиентский запрос данных в следующем методе
GetNewAssignments(int ContainerId, ref List<ExecEnv> processedList)
{
// Check the avaialability of Cotnaier in dictionary here;
if(IDToContainerList.ContainsKey(ContainerId))
{
Container cont = IDToContainerList[ContainerId];
// Get ExecEnv List copy from the requested Container and update new List
processedList = cont.ExecEnvList.Clone(); // Assume clone extension method is implemented for List
// Logic to Update NewContMod List here
}
}
The above code updates NewContMod in my cache as well. I don't want this behavior.
Я хотел, чтобы список NewContMod обновлялся только по аргументу ref обработанного списка.
Таким образом, реализованный метод Clone в ExecEnv, как показано ниже,
public object Clone()
{
var obj = (ExecEnv) this.MemberwiseClone();
obj.ExistingContModList = new ObservableCollection<ContMod>(ExistingContModList.Select(x => (ControlMod)x.Clone()).ToList());
obj.NewContModList = new ObservableCollection<ContMod>(NewContModList.Select(x => (ControlMod)x.Clone()).ToList());
return obj;
}
После этого добился всего, что я хочу. NewContModList обновляется только для аргумента processList ref. NewContModList не обновляется в исходном кеше.
Я пришел из C ++ фона, насколько я понимаю, все C# объекты являются ссылочными типами, поэтому нам нужен метод клонирования, чтобы получить копию клона. Таким образом, в приведенном выше подходе мне нужно клонировать другие объекты списка, как указано выше.
Так что мне нужна помощь экспертов, чтобы понять, есть ли лучший подход к проектированию, чтобы справиться с вышеуказанным сценарием?