Почему Cache.Add возвращает объект, представляющий кешированный элемент?
Из MSDN о различиях между добавлением или добавлением элемента кэш-памяти ASP.NET:
Примечание. Методы добавления и вставки имеют та же подпись, но есть тонкие различия между ними. Во-первых, вызов метода Add возвращает объект, представляющий кешированный элемент, при вызове вставки не. Во-вторых, их поведение разные, если вы вызываете эти методы и добавьте элемент в кэш, который уже хранится там. Вставка метод заменяет элемент, тогда как Ошибка метода добавления. [акцент мой]
Вторая часть проста. Нет вопроса об этом.
Но с первой частью, почему он хочет вернуть объект, представляющий кешированный элемент? Если я пытаюсь добавить элемент в кеш, у меня уже есть/знаю, что это за элемент?
Я не понимаю. Каковы причины этого?
Ответы
Ответ 1
Вызов Add() в кеше в конечном итоге вызывает внутренний метод с этой сигнатурой:
internal abstract CacheEntry UpdateCache(CacheKey cacheKey,
CacheEntry newEntry, bool replace, CacheItemRemovedReason removedReason,
out object valueOld);
Обратите внимание на out object valueOld
- это устанавливается для объекта, который в настоящее время находится в кеш-кеше, и возвращается в результате добавления(). Документация вводит в заблуждение, на самом деле это не тот же самый объект, который был возвращен, - какой бы объект ни находился в том же ключевом месте.
Это легко проверить с помощью следующего кода:
String x = "lorem";
String y = "ipsum";
HttpContext.Current.Cache.Add("hi", x, null, DateTime.MaxValue,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
var z = HttpContext.Current.Cache.Add("hi", y, null, DateTime.MaxValue,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
//Result:
// z == "lorem"
Ответ 2
Чтобы сделать это еще более ясным, вот консольное приложение, демонстрирующее поведение точное:
static void Main(string[] args)
{
string key = "key";
HttpRuntime.Cache.Add(key, "first", null/*no depends*/, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null/*no callback*/);
var addResult = HttpRuntime.Cache.Add(key, "second", null/*no depends*/, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null/*no callback*/);
Console.WriteLine("addResult = {0}", addResult);
Console.WriteLine("Cache[key] = {0}", HttpRuntime.Cache[key]);
}
И вывод консоли:
addResult = first
Cache[key] = first
"Второй" вызов .Add
возвращает то, что в настоящее время находится в кэше под нашим ключом, а не обновляет запись!
Ответ 3
Если вызов метода Add удался при добавлении элемента, он возвращает null.
Если ключ уже существует в кеше, метод возвращает объект. Однако в документации не говорится, возвращает ли он объект, который вы пытались поместить в кэш, или объект, уже сохраненный в кеше.
Логически он должен возвращать объект, уже находящийся в кеше, поскольку это единственная информация, которая вызывает интерес. У вас уже есть ссылка на объект, который вы пытаетесь поместить в кеш.
Ответ 4
Он возвращает объект только в том случае, если тот же объект уже был сохранен в кеше (под другим ключом, который я думаю), под тем же ключом). В противном случае он возвращает null. Документация вводит в заблуждение:
http://msdn.microsoft.com/en-us/library/system.web.caching.cache.add.aspx
Глядя на него в Reflector, оба метода, похоже, вызывают один и тот же внутренний метод: ADD возвращает старый объект, ранее сохраненный под тем же ключом, и метод INSERT просто игнорирует это значение.