What is the C# equivalent of Java’s java/util/function/BiFunction?

In Java there is an interface called BiFunction with this source:

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);

    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}

And the oracle document states that it works like this:

Represents a function that accepts two arguments and produces a result. This is the two-arity specialization of Function. This is a functional interface whose functional method is apply(Object, Object).

apply

R apply(T t, U u) Applies this function to the given arguments. Parameters: t – the first function argument u – the second function argument Returns: the function result

andThen

default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)

Returns a composed function that first applies this function to its input, and then applies the after function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the composed function. Type Parameters: V – the type of output of the after function, and of the composed function Parameters: after – the function to apply after this function is applied Returns: a composed function that first applies this function and then applies the after function Throws: NullPointerException – if after is null

I wanted to know how to implement this interface as a class or an extension method in C#, and is there a class for this in C# by default?

Answer

Rather than using functional interfaces to represent functions like Java does, C# uses delegates. There is a built in delegate – Func<T1,T2,TResult>, that represents a function with 2 parameters and a non-void return value, just like BiFunction in Java.

To apply a delegate, you just can just call them like a function/method. Example:

Func<int, int, int> add = (x, y) => x + y;

// similar to: System.out.println(add.apply(1, 2));
Console.WriteLine(add(1, 2));

If you really want to write a word there, you can write Invoke:

add.Invoke(1, 2);

It doesn’t have the andThen method, but you can write an extension method for that:

public static Func<T1, T2, R> AndThen<T1, T2, U, R>(this Func<T1, T2, U> bifunction, Func<U, R> andThen)
    => (x, y) => andThen(bifunction(x, y));