弱い参照
キャッシュみたいな。ずっと持ってるとリソース的に負荷が高いものは弱い参照が有効。
static readonly Dictionary<string, WeakReference> _cache = new Dictionary<string, WeakReference>(); static object GetValue( string key ) { if ( !_cache.ContainsKey( key ) ) { _cache[key] = new WeakReference( new object ); } var cacheValue = _cache[key].Target; if( cacheValue != null ) { return cacheValue; } var target = new object(); _cache[key].Target = target; return target; }
マルチスレッド環境においては WeakReference.IsAlive で判断はしないほうがいい。
いざ、Target を取得したときには false になっているかもしれないから。
ロックもできないしな。
ジェネリックで作ろうと思ったけど、初期化が固定されてないと出来ないことに気づいたんでやめた。
キーで初期化デリゲートよんでインスタンスもらってもいいけど。
と思いついたんで書いてみた。
public class Cache<TKey, TValue> { public delegate TValue InitializeDelegate( TKey key ); readonly InitializeDelegate _initializeDelegate; public Cache( InitializeDelegate initializeDelegate ) { _initializeDelegate = initializeDelegate; } static readonly Dictionary<TKey, WeakReference> _cache = new Dictionary<TKey, WeakReference>(); public TValue this[TKey key] { get { if ( !_cache.ContainsKey( key ) ) { _cache[key] = new WeakReference( _initializeDelegate( key ) ); } TValue cacheValue = (TValue)_cache[key].Target; if (cacheValue.Equals( default( TValue ) )) { return cacheValue; } TValue target = _initializeDelegate( key ); _cache[key].Target = target; return target; } set { _cache[key] = new WeakReference( value ); } } }
未検証。
こんなのとかも
public class Cache<TKey, TValue> where TValue : new() { public delegate TValue InitializeDelegate( TKey key ); readonly InitializeDelegate _initializeDelegate; public Cache( InitializeDelegate initializeDelegate ) { _initializeDelegate = initializeDelegate; } public Cache() : this( delegate { return new TValue(); } ) { } 以下略 }