我正在构建一个类似于LINQ的系统,并且在这样做时,我试图支持多态回调处理程序列表,并且遇到了几种问题。问我问题的简短方法是向您展示一些代码。我的新系统支持“组”,组有一个入口点向量(下面,UPDATE和CHECKPT),向量上的每个元素都是委托的多态列表,我将使用反射回调。
所以,示例代码:
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);
};
}
}
}
我的问题集中在注册行。为什么C#不能推断类型以便我可以完全省略强制转换和新的委托类型?我想从
开始 g.handlers[UPDATE] += delegate(int x, string s, double d) {
Console.WriteLine(....);
};
C#可以推断出所需的类型签名。 delegate()将是一种匿名类型,C#只会生成类似
的内容private delegate void _atype1(int _a0, string _a1, double _a2)
然后在编译行之前插入(Delegate)(_atype1)
。因此,我的用户不需要声明委托类型(当前强制她两次输入参数列表)。
我确实有System.Linq
,因为我在VS 2010上。所以如果LINQ可以某种方式推断出所需的演员阵容......
答案 0 :(得分:2)
你应该能够这样做:
g.handlers[UPDATE] += (GroupISDHandler)((x, s, d) =>
Console.WriteLine(
"my int,string,double handler was called, with x = {0}, s = {1}, d = {2}",
x, s, d));
另一种选择是:
有一个名为'Parameters'的类,它是用户可以发送的任何容器,如果它们永远不会改变则可以是已定义的类型,如果您假装发送和接收不同数量的参数,则可以是对象列表。然后代替一个委托,你将采取等于一个带有一个参数的委托的Action,你可以不进行这样的调用来执行你的调用:
p =&gt; Console.WriteLine(“x = {0},s = {1},d = {2}”,p.x,p.s,p.d);
答案 1 :(得分:0)
事实证明答案基本上是这样的:虽然你可以在我想到的各种情况下进行推理,但是C#所有者想要完全通用的解决方案和多态性使得类型推理问题太难以解决方式,在他们看来。我自己不同意,因为我最终两次输入所有类型的签名,但那是他们的推理。