1

Suppose I have a class Composite that is constructed from a dictionary of instruments and weights.

public IReadOnlyDictionary<Instrument, double> Underlyings{ get; private set; } 

public Composite(
    Id id,
    Currency currency,
    Dictionary<Instrument, double> underlyings
    )
{
    Underlyings= underlyings;
}

}

This class is exposed to the client, and I want the client to be able to modify the existing keys' values within Underlyings, but not add new key-value pairs to Underlyings.

Then making Underlyings a ReadOnlyDictionary will not work as the client code will not be able to modify the values for existing keys. So my solution was to take the wrapper around a dictionary from this answer and modify the setter for TValue IDictionary<TKey, TValue>.this[TKey key] such that existing values can be modified. But this seems like a silly solution - is there an easier way than writing a wrapper class to have a dictionary which has modifiable existing key-value pairs, but cannot have new key-value pairs added to it? Apologies for the very simplistic question.

Community
  • 1
  • 1
Eric Hansen
  • 1,749
  • 2
  • 19
  • 39
  • @Damien_The_Unbeliever Apologies if I'm misunderstanding your suggestion, but I don't think properties would work because a Composite is just a collection of Instruments, which don't inherently have a weight. The weight only belongs to the composite itself. The weights for each Instrument have to re-balanced (or changed) all the time, but they aren't inherently properties of the Instruments themselves - they only exist within the context of that Composite. And there are hundreds of different Composites. If that made any sense? – Eric Hansen May 20 '16 at 09:28

4 Answers4

1

No, there is no standard dictionary that only allows updates. Its all or nothing.

As you have discovered, you have to create it your own, or find an implementation that is already there. Overriding the Add and this[] property is a solution that might work for you.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

You can use ReadOnlyDictionary, but provide another method to modify value of given key. Something like:

Dictionary<KeyType, ValueType> _dictionary;
public ReadOnlyDictionary<KeyType, ValueType> Dictionary => new ReadOnlyDictionary<KeyType, ValueType>(_dictionary);

public void ChangeValue(KeyType key, ValueType value) => _dictionary[key].Value = value;
Sinatr
  • 20,892
  • 15
  • 90
  • 319
0

As you said, create a wrapper over a dictionary or inherit from the dictionary class an override Add.

Petre Ionescu
  • 174
  • 1
  • 8
0

Not a good way but a hack. Generate a wrapper around your data and Use a ReadOnlyDictionary which is introduced in .NET 4.5.

class MyDataWrapper<T>
{
    public T Data { set; get; }
}

var dicData = new Dictionary<int, MyDataWrapper<string>>();
dicData[0] = new MyDataWrapper<string> { Data = "0" };
dicData[1] = new MyDataWrapper<string> { Data = "0" };
var myDic = new ReadOnlyDictionary<int, MyDataWrapper<string>>(dic);

myDic[1].Data = "2";

// myDic[1] = new ... compile error
// myDic.Add() compile error
Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74