﻿# 正確的使用 ASP.NET 的 Cache 物件

我們常看到有人在 ASP.NET 裡面寫 Cache 的時候，用以下這種寫法：

> if (Cache\["KeyName"\] != null)  
> {  
>     string name = ((SomeClass) Cache\["KeyName"\]).Name;  
> }

這段 Code 在執行的時候是有風險的，因為這很有可能會發生 NullReferenceException 例外！

但為什麼會發生例外呢？！原因就在於 Cache 的設計架構是可以同時在兩個不同的 thread 中修改/刪除 Cache 中的物件，也就是在另一個使用者執行的 thread 中也有可能會透過程式直接將該 Cache 的 Key 給清掉。另一個可能是當記憶體不足時，Cache 的值也有可能會被自動清掉 ( Garbage Gollection )。所以當你執行到 string name = ((SomeClass) Cache\["KeyName"\]).Name; 的時候 ((SomeClass) Cache\["KeyName"\]) 這段程式回傳的物件就有可能是 null 而導致 NullReferenceException 例外！

所以比較正確的寫法應該是這樣：

> SomeClass class1 = Cache\["KeyName"\] as SomeClass;  
> if (class1 != null)  
> {  
>     string name = class1.Name;  
> }

這才是萬無一失的寫法！

但你可能會想問說這段程式碼跟上面那段有什麼不一樣，執行到 class1.Name 這段的時候也有可能 class1 是 null 阿，因為在 .NET 中不是所有的 參考型別 (Reference Type) 不都是傳該物件的記憶體位址嗎？是沒錯，但特別的是 Cache 是使用 [WeakReference](http://msdn2.microsoft.com/en-us/library/system.weakreference.aspx "WeakReference") 實做的，想知道細節的話，可以參考[Weak References](http://msdn.microsoft.com/en-us/library/ms404247.aspx) 、 [弱式參考](http://msdn.microsoft.com/zh-tw/library/ms404247.aspx) 或 [Understanding weak references in .NET](http://www.codeproject.com/Articles/664282/Understanding-weak-references-in-NET)。
