DEV Community

Discussion on: Can you pass local functions to a method? If so, what type is a function?

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

Yes you can.

The type for a function that returns void is Action<T> or with multiple parameters, Action<T1, T2, ...>.

The type for a function that returns a value is Func<T, TReturn> or with multiple parameters Func<T1, T2, ..., TReturn>.

So if you want to define a method that takes in a function and an int, it could look like this.

public int PlusOne(Func<int, int> f, int x)
{
    // f is used like a normal function
    var x2 = f(x);
    return x2 + 1;
}

var result = PlusOne(x => x * 2, 1024);
Enter fullscreen mode Exit fullscreen mode

PlusOne could easily be a one-liner, but made it multiple lines for demonstration purposes.

Collapse
 
baenencalin profile image
Calin Baenen

But what if I want to accept ANY kind of function? With a custom amount of args, and a custom return value?

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

Custom return value is easy. You just have to add a generic parameter(s) to the function.

public U Transform<T, U>(Func<T, U> transformFn, T value)
{
    return transformFn(value);
}
Enter fullscreen mode Exit fullscreen mode

To accept a varied amount of arguments, you will have to add method overloads with different numbers of generic type parameters. Only signatures are shown below.

V Transform<T, U, V>(Func<T, U, V> transformFn, T t, U u);
W Transform<T, U, V, W>(Func<T, U, V, W> transformFn, T t, U u, V v);
X Transform<T, U, V, W, X>(Func<T, U, V, W, X> transformFn, T t, U u, V v, W w);
// etc.
Enter fullscreen mode Exit fullscreen mode

Note that some of the types T, U, V, etc could actually be the same type. Different letters are used in case they are different.

The above code does not make sense to use in practice, but it demonstrates the concept.