4

我正在构建一个有点像 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 可以以某种方式推断出所需的演员表......

4

2 回答 2

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 => Console.WriteLine("x = {0}, s = {1}, d = {2}", px, ps, pd);

于 2010-12-11T17:35:32.613 回答
0

事实证明,答案基本上是这样的:虽然您可以在我想到的那种情况下进行推理,但 C# 所有者想要完全通用的解决方案,而多态性使得类型推理问题难以以足够通用的方式解决,在他们的看法。我自己不同意,因为我最终输入了我所有的类型签名两次,但这是他们的推理。

于 2012-01-02T18:25:16.413 回答