NumberFour
NumberFour

Reputation: 3611

Use generic base class in a collection of classes derived from generic

I'm coming to C# from Java and I was unable to find out how to resolve the following issue:

I have a generic base class:

class MyBase<T>  where T : SomeAncestorOfTs
{ ... }

and then a few specialized classes (A,B,C...) derived from it, like:

class A : MyBase<SomeSpecificT> 
{ ... }

Now somewhere in my code I would like to create a Dictionary of various descendants of MyBase: something like Dictionary<string,MyBase<>>, but that's not working.

Is there a way in C# other than doing Dictionary<String,Object>?

In Java this would be easily achieved by doing HashMap<String,MyBase<? extends SomeAncestorOfTs>>.

UPDATE: T is supposed to have a common base class (SomeAncestorOfT).

Upvotes: 2

Views: 1330

Answers (5)

This seems to work fine, does it help you?

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, MyBase> dic = new Dictionary<string, MyBase>();
        A<int> test= new A<int>();

        dic.Add("test", test);
    }
}
class MyBase
{ }
class A<T> : MyBase
{}

Upvotes: 0

Kjartan
Kjartan

Reputation: 19111

How about something like this:

public class SuperBase
{
}

internal class MyBase<T> : SuperBase
{
}


internal class A : MyBase<string>
{
    public void DoStuff()
    {
        Dictionary<string, SuperBase> _dict = new Dictionary<string, SuperBase>();

        _dict.Add("first", new MyBase<int>());
        _dict.Add("second", new MyBase<object>());
        _dict.Add("third", new MyBase<string>());
    }
}

This does not give a compilation error as it stands at least (although I can't guarantee that it won't produce other unforeseen headaches down the road).

Upvotes: 2

nvoigt
nvoigt

Reputation: 77304

The short answer is no you cannot do this in C#. MyBase<int> and MyBase<string> do not share a base class other than object. Personally, I don't see what I would do with it even if it worked syntactically.

If all those instances share a behavior, let them all implement that interface and have a dictionary of those.

Upvotes: 1

Chris
Chris

Reputation: 5514

It cannot be done like that directly. My suggestion would be to add yet another, non-generic, base class:

class MyBase
{ ... }

class MyBase<T> : MyBase
{ ... }

And then make a dictionary of that base: Dictionary<string,MyBase>

Upvotes: 4

Nikola.Lukovic
Nikola.Lukovic

Reputation: 1325

class MyBase<T>
{ ... }

class A : MyBase<SomeSpecificT> 
{ ... }

if you don't want to use Object, you can use dynamic.

var dict = new Dictionary<String, MyBase<dynamic>>();

Upvotes: 0

Related Questions