2017-02-13 12 views
1

現在の.net ConcurrentDictionaryをラップする新しいクラスを作成して、GetOrAdd \ AddOrUpdateのAddデリゲートが1回だけ呼び出されるようにします。私はネット上でいくつかのソリューションを見てきましたが、主なものはTValueを怠惰なものにすることで、多くの怠惰なアイテムが追加されるかもしれませんが、生き残りと価値のあるファクトリーを呼び出すだけです。ここc#ConcurrentDictionaryのラッピング遅延オブジェクトのAddOrUpdateがコンパイルされない

は、私が思い付くです:私の問題はAddOrUpdateの署名である

public class LazyConcurrentDictionary<TKey, TValue> 
{ 
    private readonly ConcurrentDictionary<TKey, Lazy<TValue>> concurrentDictionary; 

    public LazyConcurrentDictionary() 
    { 
     this.concurrentDictionary = new ConcurrentDictionary<TKey, Lazy<TValue>>(); 
    } 

    public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) 
    { 
     var lazyResult = this.concurrentDictionary.GetOrAdd(key, k => new Lazy<TValue>(() => valueFactory(k), LazyThreadSafetyMode.ExecutionAndPublication)); 

     return lazyResult.Value; 
    } 

    public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addFactory, Func<TKey, TValue> updateFactory) 
    { 

     // this one fails with "Cannot convert lambda expression to type 'System.Lazy' because it is not a delegate type" 
     var lazyResult = this.concurrentDictionary.AddOrUpdate(key, (k) => new Lazy<TValue>(() => addFactory(k), LazyThreadSafetyMode.ExecutionAndPublication), updateFactory); 

     return lazyResult.Value; 
    } 
} 

「それはデリゲート型でないため 『System.Lazy』を入力するラムダ式を変換できません」、私が手

私は間違っていますか?

答えて

1

この関数のupdateFactoryの意味を誤解していると思います。それはTKeyからTValueからTValueまでの関数であり、TKeyからTValueではなく、古いものから更新された値を計算する必要があります。

(あなたがそれを使用するwnatない方法に応じて)
public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addFactory, 
            Func<TValue, TValue> updateFactory) 
{ 
    var lazyResult = this.concurrentDictionary.AddOrUpdate(key, 
    (k) => new Lazy<TValue>(() => addFactory(k), 
         LazyThreadSafetyMode.ExecutionAndPublication), 
    (k,v)=>new Lazy<TValue>(()=>updateFactory(v.Value))) 
    ); 

    return lazyResult.Value; 
} 

あるいは: だから、右の構文は、おそらくようにする必要があり、もちろんの

public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addFactory, 
            Func<TKey, TValue, TValue> updateFactory) 
{ 
    var lazyResult = this.concurrentDictionary.AddOrUpdate(key, 
    (k) => new Lazy<TValue>(() => addFactory(k), LazyThreadSafetyMode.ExecutionAndPublication), 
    (k,v)=>new Lazy<TValue>(()=>updateFactory(k, v.Value)) 
    ); 

    return lazyResult.Value; 
} 
+0

、コンパイラが追加デリゲートの下にエラーを強調したので、私それを逃した、Maksimに感謝! – Ofir

関連する問題