【问题标题】:C# - Is it possible to have multiple method signatures for an Action<>?C# - Action<> 是否可以有多个方法签名?
【发布时间】:2009-08-25 13:22:14
【问题描述】:

在 C# 中,是否可以有一个对象具有多个用于 Action 或委托的方法签名?像这样:

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");
    }
}

答案似乎是否定的,那么实现这样的事情的正确方法是什么? (这试图解决的实际问题已经以不同的方式解决了,这只是好奇)

【问题讨论】:

    标签: c# delegates action


    【解决方案1】:

    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");
        }
    }
    

    【讨论】:

    • 这实际上非常接近我正在寻找的(以及我最终做的),我的问题更多的是有没有办法避免额外的功能集(“DoSomething”)被宣布。我不相信有,但我想验证一下。
    【解决方案2】:

    Delegate 类型是抽象的,只能创建基于完全类型化签名的委托。因此,在不提供Delegate 模板的情况下,不可能只为任何方法创建一个委托,但仍然可以使用现有的委托类型进行分配,例如ActionAction&lt;T&gt;

    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);
        }
    }
    

    这可以编译,但我没有出于任何目的尝试过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 2012-09-27
      • 2011-11-28
      • 1970-01-01
      相关资源
      最近更新 更多