views:

25

answers:

1

Hi,

I'm trying to implement a class in a Silverlight 4 RIA Services application that manages different ObservableCollections that are used for data binding. These ObservableCollections need to be identified by a string name and an integer classID, which I have implemented by nesting Dictionary objects in a Dictionary> object. The problem is, if I have explicit Entity types (which I do), this structure does not seem to work. The problem seems to occur when I am trying to put an ObservableCollection into an ObservableCollection (my guess as to how a generic entity list would be implemented).

For example:

  this.rawData = new Dictionary<int, ObservableCollection<DataRaw>>();
  this.constData = new Dictionary<int, ObservableCollection<SystemConstant>>();

  this.masterData = new Dictionary<string, Dictionary<int, ObservableCollection<Entity>>>();

  masterData.Add("test", rawData);  <--- ERROR OCCURS HERE, 'best overloaded method has invalid arguments'

Note that I have tried using 'Object' instead of 'Entity' in the instantiation of masterData, but that did not solve the problem (it was admittedly a feeble attempt).

Thanks in advance for your insights. If there is a much better pattern I could be implementing here, I am open to being flexible. I mainly want to avoid having to code a bunch of Entity-type specific logic to manage the updating of this class. It seems like this should be generalizable.

Alex

A: 

For this to work you will have to declare RawData using the parent type, like this:

 this.rawData = new Dictionary<int, ObservableCollection<Entity>>();

Even if this dictionary will only hold instances of DataRaw, and even if DataRaw is derived from Entity, it is not possible to make an implicit conversion between ObservableCollection<DataRaw> and ObservableCollection<Entity>. For a moment I hesitated on whether C# would be able to solve this using variance, but after a quick proof of concept it was clear it cannot:

        var dataRaw = new DataRaw();
        Entity testEntity = dataRaw;

        var entityObservable = new ObservableCollection<Entity>();

        entityObservable.Add(dataRaw); // This is OK

        var dataRawObservable = new ObservableCollection<DataRaw>();
        dataRawObservable.Add(dataRaw); // This is fine too.

        entityObservable = dataRawObservable; // This is not valid

        var metaDictionary = new Dictionary<Int32, ObservableCollection<Entity>>();

        metaDictionary.Add(1, dataRawObservable); // This isn't valid either.

        metaDictionary.Add(2, entityObservable); // This is valid.
Murven