Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Both Action and Func<T> without explicit casting

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?

like image 788
Alfort Avatar asked Jul 10 '12 18:07

Alfort


2 Answers

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; });
like image 159
Lee Avatar answered Nov 17 '22 15:11

Lee


Try specifying the generic type parameter explicitly:

Receive<int>(B);
like image 43
Steve Czetty Avatar answered Nov 17 '22 16:11

Steve Czetty