2016-04-06 31 views
0

Dizeleri iki katına eşleyen bir sözlüğe sahibim. o, bulunmazsa eğer, 0 döndürür, 0 varsayılan değeri ekleyin branchProbability eklemek, yeni değer = 0 + branchProbability ayarlayın:Sözlüke etkili bir şekilde bir öğe eklemek ancak + = yerine = =

leaves[child.Value] += branchProbability; 

Çünkü yerine yapmanın çöker:

Bu çizgi var bir KeyNotFoundException atar anahtar üzerinde bir şey yaparak başlar. Aklıma

tek şey:

if(!leaves.ContainsKey(child.Value)) 
    leaves[child.Value] = branchProbability; 
else 
    leaves[child.Value] += branchProbability; 

Ama bunun için içeren ekstra arama gerektirir.

İçindekiler çeklerinden sakınırken bunu yapmanın daha verimli bir yolu var mıydı?

+2

Anahtarı yaratacak olan 'TryGetValue' kullanabilir ve (0.0 varsayılan değeri vardır, bu durumda, bir çift, içinde) Sözlük-değeri için kullanılan tip varsayılan değerini geri dönebilirler. Bence kendi önerdiğiniz çözüm çok daha okunaklı ve anlaşılabilir. –

+0

Alternatif olarak, [bu yanıt] (http://stackoverflow.com/a/2601501/717088), varsayılan değerler için uzantı yöntemleri oluşturulmasını önerir. Aynı soruya, bir "DefaultableDictionary" sınıfının bir uygulamasını yaratan [başka bir cevap] (http://stackoverflow.com/a/7061653/717088) de var. –

cevap

2

Aşağıdaki kod, +='u kullanarak bunu yapmanıza izin verecek bir sınıfı (ve bunları LinqPad'e yapıştırırsanız) tanımlar. Ancak, sözlüğü çok fazla yerlere aktarıyorsanız, işe yaramaz, çünkü dizinleyiciyi geçersiz kılmak yerine new ile gizlemek zorundadır (Dictionary'ın dizinleyici sanal değildir). hariç - Bunu aşmanın

bir yolu IDictionary<TKey, TValue> bir uygulamacı olarak ve bir Dictionary olan, gizli elemana sahip sınıfın içinde DefaultingDictionary oluşturarak ve bu kadar IDictionary üzerine yöntemlere tüm çağrıları devrederek olurdu indeksleyici, kendiniz yaparsınız. Bunu hala bir Dictionary bekleyen şeylere aktaramazsınız, ancak bunun yerine bir IDictionary kabul etmek için bunları değiştirebilirsiniz.

void Main() 
{ 
    var dict = new DefaultingDictionary<string, double>(); 

    dict["one"] = 1; 

    dict["one"] += 1; 
    dict["two"] += 1; 

    Console.WriteLine(dict["one"]); 
    Console.WriteLine(dict["two"]); 
} 

class DefaultingDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
{ 
    public new TValue this[TKey key] 
    { 
     get 
     { 
      TValue v; 
      if(TryGetValue(key, out v)) 
      { 
       return v; 
      } 
      return default(TValue); 
     } 

     set 
     { 
      base[key] = value; 
     } 
    } 
} 

Doğrusu, bu işin Hepsi birçok sadece += şey yapmak mümkün değildir. Gerçekten sadece çekini yapmalısın. Bunun için bir performans avantajı yok, sadece kodunuzu daha karmaşık hale getirir. Eğer kontrolü yaparsanız, onu okuyan biri tam olarak neler olduğunu anlayacaktır.

-3

Çok fazla şey yapıp yapamayacağınızdan emin değilim, belki de yerine üçlü bir operatörün tanıtımını yaparsınız. Fakat okunabilirlik açısından, yapmış olduğunuz şekilde öneriyorum.

leaves[child.value] = leaves.ContainsKey(child.value) 
        ? leaves[child.value] + branchProbability 
        : branchProbability; 
İlgili konular