C# - 是否可以为Action<>?设置多个方法签名?

时间:2009-08-25 13:22:15

标签: c# delegates action

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

答案似乎不是,那么实现类似的东西的正确方法是什么? (这个试图解决的实际问题已经以不同的方式解决了,这只是好奇心)

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:0)

Delegate类型是抽象的,只能创建基于完全类型签名的委托。因此,如果不提供Delegate模板,就无法创建任何方法的委托,但仍可以使用现有委托类型进行分配,例如ActionAction<T>:< / p>

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

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