I am trying to remove duplicate code for collections of System.Func with variable numbers of arguments. (This is used to allow code to "hook" into the logic of other components.) So I am trying to remove several almost identical methods and use generic methods instead.
To make it work I wrapped them in a HookContainer class and made it implement a common interface.
public interface IHookContainer
{
void Add<TFunc> (string filterName, int priority, KeyValuePair<string, TFunc> action);
}
public class HookContainer<T>:IHookContainer
{
Dictionary<string,OrderedDictionary<string,T>> dict = new Dictionary<string, OrderedDictionary<string, T>> ();
public void Add<T> (string filterName, int priority, KeyValuePair<string, T> action)
{
// Add an item to the Dictionary
}
}
This allows me to put them all in a single Dictionary which I can access with the Type
Dictionary<Type,IHookContainer> containers = new Dictionary<Type, IHookContainer> (){
{
typeof(HookContainer<System.Func<object,object>>),new HookContainer<System.Func<object,object>>()
},
// More dictionary entries like this (with more parameters)
};
public string AddFilter<T> (string filterName, T action, string filterTag = null, int priority=0)
{
KeyValuePair<string, T> data = new KeyValuePair<string, T> (filterTag, action);
if (containers.ContainsKey (typeof(T))) {
IHookContainer container = containers [typeof(T)];
container.Add<T> (filterName, dictPriority, data);
}
return filterTag;
}
Now I get a compile error saying:
cannot convert `System.Collections.Generic.KeyValuePair<string,T>'
expression to type `System.Collections.Generic.KeyValuePair<string,T>'
So it's apparently lacking some information that I take for granted. Or I am thinking wrong. Or both. Why can't it convert a type to ...itself??
I apparently cannot use the same Type parameter from the Generic class for the generic method if the implemented interface. Sadly, the type cannot be inferred either. Is there any way to make this work?
There is also a warning that the type paramater name is the same as the outer type paramemter. Can I tell the compiler that this is completely intended?
Thanks for any help. I am using C# 4.0
Update:
I can get the code to work by declaring the HookContainer with a second Type parameter and using this for passing it into the Add method.
So it looks like this now:
public class HookContainer<T,U>:IHookContainer
{
Dictionary<string,OrderedDictionary<string,T>> dict = new Dictionary<string, OrderedDictionary<string, T>> ();
public void Add<U> (string filterName, int priority, KeyValuePair<string, T> action)
{
// Add an item to the Dictionary
}
}
This, of course requires me to redundantly pass the Type of the Container twice when declaring the Dictionary:
Dictionary<Type,IHookContainer> containers = new Dictionary<Type, IHookContainer> (){
{
typeof(HookContainer<System.Func<object,object>,System.Func<object,object>>),new HookContainer<System.Func<object,object>,System.Func<object,object>>()
}
};
So while this might work, it looks and feels ridiculous. Is there any way to just (re)use a single Type parameter?