title: Concise way to do a plus equals operation on a Dictionary element that might not be initialized
body: <p>I'm looking for an extension method or any other suggestion that can help me make this code as concise as possible.</p>
  
  <pre><code>foreach( Layer lyr in this.ProgramLayers )
    foreach( UWBCEvent evt in this.BcEvents.IncludedEvents )
      EventGroupLayerLosses[new EventGroupIDLayerTuple(evt.EventGroupID, lyr)] += 
         GetEL(evt.AsIfs, lyr.LimitInMillions, lyr.AttachmentInMillions);
  </code></pre>
  
  <p>The above code has a fairly clear purpose, I'm bucketing values into groups with a compound key. However, this code will fail because the dictionary is initially empty and the += operator won't know to start the bucket off at 0.</p>
  
  <p>The best I can come up with is this:</p>
  
  <pre><code>public V AddOrSet&lt;K, V&gt;(this Dictionary&lt;K, V&gt; dict, K key, V value)
  {
      if( dict.ContainsKey(key) )
          dict[key] += value;
      else
          dict[key] = value;
  }
  </code></pre>
  
  <p>But of course, even that won't compile because there's no way to restrict the type of V such that the operator <code>+=</code> exists.</p>
  
  <p><strong>Rules</strong></p>
  
  <ul>
  <li>Only one iteration through the double for loop. Not allowed to loop through once before to initialize the dictionary with 0 values.</li>
  <li>Helper method or extension method can be used, but I want the inner loop to be a one liner.</li>
  <li>Be as generic and reusable as possible so that I don't need to create a bunch of identical functions for similar bucketing with different types (decimals, ints, etc).</li>
  </ul>
  
  <hr>
  
  <p>For reference - elsewhere in the class the key is defined as an actual Tuple (just with named parameters), which is why it can be used as a dictionary key:</p>
  
  <pre><code>private Dictionary&lt;EventGroupIDLayerTuple, Decimal&gt; _EventGroupLayerLosses;
  public class EventGroupIDLayerTuple : Tuple&lt;Int32, Layer&gt;
  {
      public EventGroupIDLayerTuple(Int32 EventGroupID, Layer Layer) : base(EventGroupID, Layer) { }
      public Int32 EventGroupID { get { return this.Item1; } }
      public Layer Layer { get { return this.Item2; } }
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Solution</strong></p>
  
  <p>Thanks to Jon Skeet for the idea of passing a Lambda function as a third parameter to my extension method. No need to even restrict it to a += operation anymore. It's generic enough any operation can be passed to set the new value if a value already exists.</p>
  
  <pre><code>//Sets dictionary value using the provided value. If a value already exists, 
  //uses the lambda function provided to compute the new value.
  public static void UpdateOrSet&lt;K, V&gt;(this Dictionary&lt;K, V&gt; dict, K key, V value, Func&lt;V, V, V&gt; operation)
  {
      V currentValue;
      if( dict.TryGetValue(key, out currentValue) )
          dict[key] = operation(currentValue, value);
      else
          dict[key] = value;
  }
  </code></pre>
  
  <p>Examples:</p>
  
  <pre><code>mySums.UpdateOrSet("Bucket1", 12, (x, y) =&gt; x + y);
  myStrs.UpdateOrSet("Animals", "Dog", (x, y) =&gt; x + ", " + y);
  myLists.UpdateOrSet("Animals", (List&lt;T&gt;) Dogs, (x, y) =&gt; x.AddRange(y));
  </code></pre>
  
  <p>Endless fun!</p>