I have a question about C# generics and delegate:
First I describe the general question—I want a collection of delegates, these delegates should have a similar form, for example, all my delegates should have the form:take two parameters of the same type, and return int. I guess the best way to model these delegates is by using generic delegate:
public delegate int MyFunctionDel <T> (T a, T b);
But how can I create a collection of MyFunctionDel with different type? I cannot declare this:
List<MyFunctionDel <T>> mylist; //Compile error: cannot find type T
And secondly, here is what I am actually trying to do. What I am trying to do could be solved by the above question. But you can give alternative solutions.
I wrote a collection-like structure: it can hold any type of data. But all the data in the structure should be of the same type. Unfortunately, this structure is not generic for some historical reason. This structure has a Compare method.
But now I need to provide customized comparers for some specific type. And the behavior I want is: the struture uses customized comparer if there is one for the type of data in it, otherwise uses the original Compare method. Here is my demo code:
/*
*This piece of code demonstates my idea, but never works
*/
static class Program
{
[STAThread]
static void Main()
{
MyStructure s = new MyStructure ();
//create a customized comparer using Comparison<T> generic delegate
Comparison <string> myStirngComparer = (x , y)=> {
return -x.CompareTo(y);
};
s.CustomizedComparers[typeof(string)] = myStirngComparer;
System.Console.WriteLine (s.Compare("a" , "b")); //I am expecting the result to be 1
}
}
class MyStructure
{
//For simplicity, I won't put storage related code here
public int Compare (object o1, object o2)
{
//let's suppose o1 and o2 are always of same type
switch (o1.GetType())
{
case TypeCode.Single: return Compare<Single> ((Single)o1 , (Single)o2);
case TypeCode.Double: return Compare<Double> ((Double)o1 , (Double)o2);
case TypeCode.String: return Compare<String> ((String)o1 , (String)o2);
//and so on.....
}
return 0;
}
//NOTE: code below won't work
//But my logic is: use a Dictionary to store a map from "Type" to "Comparison<T>"
//When doing the comparison, we first examine if there exists one Comparison<T> for
//Type T in the Dictionary
//Compile failed here
public Dictionary <Type , Comparison<T> > CustomizedComparers = new Dictionary <Type , Comparison<T> > ();
private int Compare<T> (T a , T b)
{
if (CustomizedComparers.ContainsKey(typeof(T)))
{
Comparison<T> comp = CustomizedComparers[typeof(T)];
return comp (a , b);
}
else return Comparer<T>.Default.Compare(a, b);
}
}
Any comments, suggestions and insights are welcomed! Thank you guys.
You can create
Dictionary<Type, Delegate>and cast delegates to correct type when they are requested. Consider following helper class instead of plainDictionary<Type, Delegate>:Now you can use:
and