7

I have a class that has to receive methods in order to call them as well as doing other executions. These methods have to be used many times and for many different users so the simpler the better.

To deal with this I have two methods:

    void Receive(Action func)
    {
        // Do some things.
        func();
    }

    T Receive<T>(Func<T> func)
    {
        // Do some things.
        return func();
    }

(Actually I have 34 methods to be able to receive any of the different Action or Func defined.)

Then, I want to be able to pass any method as a parameter to the Receive function, to be able to do something like this:

    void Test()
    {
        Receive(A);
        Receive(B);
    }

    void A()
    {
    }

    int B()
    {
        return 0;
    }

Just like this, it gives me one error in Receive(B):

The call is ambiguous between the following methods or properties: 'Class1.Receive(System.Action)' and 'Class1.Receive<int>(System.Func<int>)'

Ok, the signature is the same (although no error is shown if I don't use the methods).

If I remove the Receive(Action) method, I get in Receive(A) the following error:

The type arguments for method 'Class1.Receive<T>(System.Func<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

But my type in this case is void and it is forbidden to use it as a generic parameter.

So, is there a way to have my Receive method without using any explicit cast of Action or Func?

Alfort
  • 91
  • 1
  • 1
  • 9

2 Answers2

4

No you can't do this - void is not a valid return type for Func<T>. The best you could do is to wrap it in a Func<object>:

Receive(() => { A(); return null; });
Lee
  • 142,018
  • 20
  • 234
  • 287
  • I get the same compilation error with this code. But a `return 0;` or `return true;` worked! Thank you! – Rami A. Feb 28 '16 at 00:01
3

Try specifying the generic type parameter explicitly:

Receive<int>(B);
Steve Czetty
  • 6,147
  • 9
  • 39
  • 48
  • With this, if I have a method with, for example, four parameters I still have to do a cast and include all of them. Ex.: Receive,string,int,int>(C,myObject1,string1,int1,int2) – Alfort Jul 11 '12 at 17:03
  • It's not really casting in this case (everything happens at compile-time), but I see what you mean. Are you sure you need such a general-case set of methods? – Steve Czetty Jul 11 '12 at 17:08
  • Yes, it is a general purpose class that has to be able to accept any kind of method. – Alfort Jul 12 '12 at 07:23