I'm building a system a bit like LINQ, and in doing it, am trying to support polymorphic callback handler lists, and am running into several kinds of problems. The short way to ask my question is to just show you some code. My new system supports "Groups" and groups have a vector of entry points (below, UPDATE and CHECKPT) and each element on the vector is a polymorphic list of delegates, which I'll call back using reflection.
So, sample code:
namespace ConsoleApplication1
{
internal delegate void GroupISDHandler(int i, string s, double d);
class Group
{
public class myHandlers {
internal List<Delegate> hList = new List<Delegate>();
public static myHandlers operator +(myHandlers a, Delegate b) {
a.hList.Add(b);
return a;
}
}
public class mimicVector {
public List<myHandlers> ListofhLists = new List<myHandlers>();
public myHandlers this[int i] { get { return ListofhLists[i]; } set { ListofhLists[i] = value; } }
}
public mimicVector handlers = new mimicVector();
public Group(string name) { ... }
}
class Program
{
internal const int UPDATE = 0;
internal const int CHECKPT = 1;
public static void Main()
{
Group g = new Group("group name");
g.handlers[UPDATE] += (GroupISDHandler)delegate(int x, string s, double d) {
Console.WriteLine("my int,string,double handler was called, with x = {0}, s = {1}, d = {2}",
x,s,d);
};
}
}
}
My questions centers on the registration line. Why can't C# infer the types so that I could omit the cast and the new delegate type entirely? I would think that from
g.handlers[UPDATE] += delegate(int x, string s, double d) {
Console.WriteLine(....);
};
C# could infer the needed type signature. delegate() would be a kind of anonymous type and C# would just generate something like
private delegate void _atype1(int _a0, string _a1, double _a2)
and then insert (Delegate)(_atype1)
before compiling the line. Thus my user won't need to declare a delegate type (which currently forces her to type the argument list twice, in effect).
I do have System.Linq
since I'm on VS 2010. So if LINQ can somehow infer the needed casts...
Turns out that the answer is basically this: while you can do the inference in the kinds of situations I had in mind, the C# owners want completely general solutions and polymorphism makes the type inference problem too hard to solve in a sufficiently general way, in their view. I myself disagree since I end up typing all my type signatures twice, but that's their reasoning.