Leaders snarfblam Posted September 20, 2006 Leaders Posted September 20, 2006 I posted this class definition on another thread and decided that it would be a good idea to post it in the Code Library as well. It is a generic, global object caching class, working in a dictionary-like manner (and, in fact, backed by a Dictionary<string, TValue> object). Because of the way that .Net handles fields of static classes you are provided a complete and separate cache for each type. (Or, to be more accurate, for each type parameter. For example, you can store a Bitmap in Cache<Image> and it will not be found in Cache<Bitmap>. Likewise, a Bitmap stored in Cache<Bitmap> will not be found in Cache<Image>.) The Cache class provides indexers and enumerators, and is implemented in a manner that makes the use of keys to identify objects completely optional. static class Cache<T> { // Backing collection static Dictionary<string, T> values; static Cache() { // Create a dicationary with case-insensitive strings for keys. values = new Dictionary<string, T>(StringComparer.InvariantCultureIgnoreCase); } public static T GetItem(string key){ return values[key]; } #region Add/Remove methods /// <summary> /// Adds an object with a specified key to the cache. /// </summary> /// <param name="key">The key under which the object is stored.</param> /// <param name="value">The object to store.</param> public static void Add(string key, T value){ values.Add(key, value); } /// <summary> /// Adds an object to the cache, generating a key automatically. /// </summary> /// <param name="value">The value to store.</param> public static void Add(T value){ values.Add( //Create a key based on the object's hash code, ideally //ensuring that unique objects obtain unique keys. value.GetHashCode().ToString(), value); } /// <summary> /// Removes an object from the cache by specifying the key. /// </summary> /// <param name="key">The key of the object to remove from the cache.</param> /// <returns>A value indicating success or failure of the operation.</returns> public static bool Remove(string key) { return values.Remove(key); } /// <summary> /// Removes an object from the cache by specifying the key. /// </summary> /// <param name="value">The object to remove from the cache.</param> /// <returns>A value indicating success or failure of the operation.</returns> public static bool Remove(T value) { string key = null; foreach(KeyValuePair<string, T> item in values){ if(item.Value.Equals(value)) { key = item.Key; break; } } if(key == null) return false; return values.Remove(key); } /// <summary> /// Removes any items from the cache where the item meets the condition specified. /// </summary> /// <param name="condition">A delegate which processes an item and returns a boolean value /// indicative of whether or not the value meets a condition.</param> public static void Remove(Predicate<T> condition) { string[] keys = new string[values.Count]; values.Keys.CopyTo(keys, 0); foreach(string key in keys) { if(condition(values[key])) values.Remove(key); } } /// <summary> /// Removes any items from the cache where the key meets the condition specified. /// </summary> /// <param name="condition">A delegate which processes a key and returns a boolean value /// indicative of whether or not the value meets a condition.</param> public static void Remove(Predicate<string> condition) { string[] keys = new string[values.Count]; values.Keys.CopyTo(keys, 0); foreach(string key in keys) { if(condition(key)) values.Remove(key); } } /// <summary> /// Removes all items from the cache. /// </summary> public static void Clear() { values.Clear(); } #endregion #region Enumerators /// <summary> /// Gets an enumerable collection of all the objects stored in the cache. /// </summary> public static IEnumerable<T> Values { get { return values.Values; } } /// <summary> /// Gets an enumerable collection of all the keys that identify objects in the cache. /// </summary> public static IEnumerable<string> Keys { get { return values.Keys; } } #endregion } The Cache<T> class generally performs the same function that a statically declared Dictionary<TKey, TValue> object would, but it can be more convinient to write code with, and, again, the use of keys is optional. Unfortunately, because of a technical issue (overloading), Cache<string> will be difficult if not impossible to use. Here is an example of using the Cache<T> class. public void Example(){ // It could be handy to cache bitmaps that will be used application-wide. Cache<Image>.Add("OpenIcon", Image.FromFile(IconPath.OpenIcon)); Cache<Image>.Add("CloseIcon", Image.FromFile(IconPath.CloseIcon)); // Be careful--generics do not respect inheritance. // (They can't due to the way that .Net handles static members of generic classes.) // Throws exception because object is not cached in Cache<Bitmap>. Image OpenImage = Cache<Bitmap>["OpenIcon"]; // Works OpenImage = Cache<Image>["OpenIcon"]; // Cache is enumerable. // Let's display the contents of Cache<Image> using an image displaying form. foreach(string key in Cache<Image>.Keys) { // Create the form with the key for the caption and the associated image within the form. frmImageDisplay = new ImageDisplayForm(key, Cache<Image>[key]); // And show. frmImageDisplay.ShowDialog(); } } Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.