2

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

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

4

2 回答 2

4

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

这个问题的解决方案是什么?

我不清楚实际问题是什么。这可能是您正在寻找的:

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");
    }
}
于 2009-08-25T13:25:38.700 回答
0

Delegate类型是抽象的,只能创建基于完全类型化签名的委托。因此,在不提供模板的情况下,不可能只为任何方法创建委托Delegate,但仍然可以使用现有的委托类型进行分配,例如Actionor 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);
    }
}

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

于 2009-08-25T13:51:09.700 回答