I have a generic class named Manager<T>
, and I want to create a dictionary that maps a type to an instance of the Manager class of this type.
I thought about creating a Dictionary class that derives from Dictionary
, but overriding all of its methods seems overkill.
Ideas? Thanks.
4 Answers
Assuming that your dictionary needs to hold managers with mixed type arguments, you can implement an IManager
interface in Manager<T>
, make a Dictionary<Type,IManager>
, and add a generic wrapper to cast instances back to Maanger<T>
, like this:
interface IManager {
// Properties and methods common to all Maanger<T>, regardless of T
}
class Manager<T> : IManager {
}
class Main {
private readonly IDictionary<Type,IManager> managers =
new Dictionary<Type,IManager>();
bool TryGetManager<T>(Type key, out Manager<T> manager) {
IManager res;
return managers.TryGetValue(key, out res) ? ((Manager<T>)res) : null;
}
}

- 714,442
- 84
- 1,110
- 1,523
-
-
@LukeMcGregor If I understood the question correctly, the idea was to store generic instances in a dictionary; having a generic dictionary was not a goal in itself. To that end, the sample does what the OP wants: he gets to look up a `Manager
` by the `Type` of his `T`, getting a generic back. – Sergey Kalinichenko Dec 24 '11 at 11:59 -
You actually lose the genericness entirely with this, eg string DoSomething(T val) would be converted to string DoSomething(object val) by IManager and even if you actually make a generic version you have to preserve the object version for the sake of the interface. TBH IManager would be much better as a marker interface, at least then the only impact would be a cast on the way out of the dictionary. – undefined Dec 24 '11 at 12:09
-
@LukeMcGregor I think I know why you got confused: I declared `TryGetManager
(Type,T manager)` instead of `TryGetManager – Sergey Kalinichenko Dec 24 '11 at 12:16(Type, Manager manager)`. I have now fixed it. The interface is non-essential to the solution: he might as well have `object` in the dictionary. -
Dictionary
isn't particularly nice as it doesn't ensure any type safety on the stored item – undefined Dec 24 '11 at 12:19 -
@LukeMcGregor Think about it carefully: there's absolutely nothing else it can do. Unless you add a common interface as I suggested, `System.Object` would be the only common ancestor type of all `Manager
`. – Sergey Kalinichenko Dec 24 '11 at 12:26 -
1Your solution would be much better if IManager was simply a marker interface ie empty, however it still kinda doesnt solve the problem – undefined Dec 24 '11 at 12:36
-
@LukeMcGregor Whether or not it should be a marker is up to the OP to decide. As far as solving the OP's problem, it's the *only* answer on the page that addresses the "create a dictionary that maps a type to an instance of the Manager class of this type" requirement. – Sergey Kalinichenko Dec 24 '11 at 12:42
i think this is a case generics doesnt support nicely, prehaps this is what you want. You will need to store managers internally to this, for the storage prehaps use a Dictionary<Type,Object>
or Dictionary<Type,IManager>
where IManager is a marker (empty) interface applied to Manager<T>
You will then need to cast this to the type T provided before returning it. I cant think of a good way to access this via an indexer so this may be the best you can get to
public class ManagerDictionary{
private Dictionary<Type, object> _managers = new Dictionary<Type, object>();
public Manager<T> GetManager<T>()
{
if (_managers.ContainsKey(typeof(T)))
{
return _managers[typeof(T)] as Manager<T>;
}
throw new ArgumentException("No manager of " + typeof(T).Name + " could be found");
}
public void AddManager<T>(Manager<T> manager)
{
_managers.Add(typeof(T),manager);
}
}

- 33,537
- 22
- 129
- 198
-
How does this address the "create a dictionary that maps a type to an instance of the Manager class of this type" requirement from the OP? – Sergey Kalinichenko Dec 24 '11 at 12:42
-
It doesnt create an IDictionary, what it does do is create a way of getting a provided instance of a specific Manager
for the type T which is what i understand the intent of the question to be – undefined Dec 24 '11 at 12:47 -
I think the header of the OP is misleading. Inside the post he clearly states: "I want to create a dictionary that maps a *type* to an instance of the *Manager class of this type*.", while the title suggests that he wants to map *an instance of type T* to an instance of the Manager class of this type. The former makes sense (and is in fact a common problem to solve), while the later does not make much sense outside of rather contrived examples. – Sergey Kalinichenko Dec 24 '11 at 12:52
-
-
-
I suppose it is similar... prehaps i didnt fully understand what you were getting at. I do however think that its important not to put any content into IManager if you have it as that will break type safety. I also think its important to wrap this in a class to group it together. Otherwise yes they are very similar so downvote removed – undefined Dec 24 '11 at 13:18
For this to work you really need to have an interface that T derives from. Then your manager class can work with whatever concrete T you pass in.
class Manager<T> where T: IMyClass
This is good practice as the methods on the interface are what make T generic.
For more ideas you could look at the Command Pattern
You are going to have some sort of switch or dictionary to maintain, but you should be able to get a good solution.

- 6,573
- 4
- 29
- 41
I think this code would make it:
class ManagerDictionary<T> : Dictionary<T, Manager<T>> {
}

- 9,165
- 5
- 37
- 58
-
This does not address the "create a dictionary that maps a type to an instance of the Manager class of this type" requirement from the OP. The headline is misleading, because Dictionary
> is certainly *not* what the OP is looking for. – Sergey Kalinichenko Dec 24 '11 at 12:44 -
This will only map a single type to a manager of that type. ie it will allow mapping the string "hello" to an instance of Manager
which isnt really the intention – undefined Dec 24 '11 at 13:21
>
– undefined Dec 24 '11 at 12:28