tags:

views:

59

answers:

1

I've a base type from which 3 different objects are inherited. Lets call the base object B, and inherited ones X, Y, and Z. Now I've dictionaries with an int as key and respectively X, Y, Z as value.

I've a control that will need to do lookups in one and only one of the specific dictionaries to draw itself but to be able to work with all three of my dictionaries I tried specifying that the control should take an argument equal to Dictionary<int, B>. That didn't work though.

So what are my options? I want my control to work with all dictionaries of the form <int, B>.

+7  A: 

Make a generic method like this:

public void DoSomething<T>(IDictionary<int, T> dictionary) where T : B

Or similarly make the control itself generic (which will give your designer issues, but...)

public class MyControl<T> where T : B
{
    private IDictionary<int, T> dictionary;
    ...
}

You need to do this due to generic invariance. Even in C# 4 (which supports some variance) this would be invariant: a dictionary uses the values for both input and output.

Imagine you could convert from Dictionary<int, X> to Dictionary<int, B>. You'd then be able to write:

dictionary[0] = new B();

... which clearly wouldn't be valid for the dictionary, as it's not an X...

Jon Skeet
Note: The latter option is only viable when the Control takes one of the three specific types throughout its lifetime. The first option allows you to switch types as needed.
Joren
Worked like a charm! I can't believe how I missed that. I added <T> to the class definition with where T : B and then in the constructor I took a Dictionary<int, T> object. Awesome answer. The control doesn't need to variate which type is used. Each control only uses one for a whole lifetime.
Qua