代码之家  ›  专栏  ›  技术社区  ›  Dugan

C-一个操作是否可以有多个方法签名<>?

  •  2
  • Dugan  · 技术社区  · 15 年前

    在C中,是否可能有一个对象对一个操作或委托具有多个方法签名?这样地:

    class Foo
    {
        public Action<string> DoSomething;
        public Action<string, string> DoSomething;
    }
    
    class Bar
    {
        public Bar()
        {
            Foo f1 = new Foo();
            f1.DoSomething = (s) => { Console.Write(s) };
            Foo f2 = new Foo();
            f2.DoSomething = (s1, s2) => { Console.Write(s1 + s2) };
    
            f1.DoSomething("Hi");
            f2.DoSomething("Hi","World");
        }
    }
    

    答案似乎是否定的,那么实现类似的东西的正确方法是什么呢?(本次尝试解决的实际问题已经以不同的方式解决了,这只是好奇而已)

    2 回复  |  直到 15 年前
        1
  •  4
  •   Mehrdad Afshari    15 年前

    delegate 是一个抽象的 单一方法 (当然,几个具有相似签名的方法可以由一个委托来表示,但是从调用方的角度来看,它的行为就像一个方法,所以在这里不相关。)一个方法具有多个签名是没有意义的。因此,委托实例具有特定的签名。重载解决方案对代理没有任何意义。这不是你选择的方法组。您直接指向一个方法并说“调用这个”。

    这个问题的解决办法是什么?

    我不清楚实际的问题是什么。这可能是你想要的:

    class Foo {
        public Action<string> DoSomethingDelegate1;
        public Action<string,string> DoSomethingDelegate2;
        public void DoSomething(string s) { DoSomethingDelegate1(s); }
        public void DoSomething(string s, string t) { DoSomethingDelegate2(s, t); }
    }
    
    class Bar
    {
        public Bar()
        {
            Foo f1 = new Foo();
            f1.DoSomethingDelegate1 = (s) => { Console.Write(s) };
            Foo f2 = new Foo();
            f2.DoSomethingDelegate2 = (s1, s2) => { Console.Write(s1 + s2) };
    
            f1.DoSomething("Hi");
            f2.DoSomething("Hi","World");
        }
    }
    
        2
  •  0
  •   Cecil Has a Name    15 年前

    这个 Delegate 类型是抽象的,只能创建基于完全类型签名的委托。因此,不提供 代表 模板,但仍可以使用现有委托类型进行分配,例如 Action Action<T> :

    class Foo
    {
        public Delegate Target { get; set; }
    
        public void Fire()
        {
            if (Target != null)
            {
                var pinfos = Target.Method.GetParameters();
                object[] args = new object[pinfos.Length];
                for (int i = 0; i < pinfos.Length; i++)
                {
                    // Attempt to create default instance of argument:
                    args[i] = Activator.CreateInstance(pinfos[i].ParameterType);
                }
                Target.DynamicInvoke(args);
            }
        }
    }
    
    class Bar
    {
        public void Huppalupp()
        {
            Foo f = new Foo();
            f.Target = new Action(MethodThatTakesNothing);
            f.Fire();
            f.Target = new Action<string>(MethodThatTakesAString);
        }
    
        void MethodThatTakesNothing()
        {
            Console.WriteLine("Absolutely nothing.");
        }
    
        void MethodThatTakesAString(string s)
        {
            Console.WriteLine(s);
        }
    }
    

    这是汇编,但我没有为任何目的而尝试过。