C # - Is it possible to have multiple method signatures for Action <>?

In C #, is it possible to have an object that has multiple method signatures for an Action <> or delegate? Like this:

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

      

The answer doesn't seem to be the same, so is this the correct way to implement something like this? (The actual problem I was trying to solve was solved differently, it's just curiosity at this point)

+2


source share


2 answers


A delegate

is an abstraction of a single method (of course, multiple methods with similar signatures can be represented by the same delegate, but from the caller's point of view, it behaves like a single method, so it doesn't matter here). It doesn't make sense for a single method to have multiple signatures. Hence, the delegate instance has a specific signature. Overload resolution is irrelevant to delegates. This is not a group of methods that you choose. You point directly to the method and say "name it".

What's the solution to this problem?



I'm not clear on what the real problem is. This might be what you are looking for:

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

      

+4


source


The type Delegate

is abstract and only delegates based on fully typed signatures can be created. Thus, it is not possible to simply create a delegate for any method without providing a template Delegate

, but it is still possible to assign using an existing delegate type such as Action

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

      



This compiles, but I haven't tried it for a purposeful purpose.

0


source







All Articles