5

In Java, the Supplier interface represents a function with no arguments and a generic return value.

Supplier<String> randomPasswordSupplier = () -> "secret";
String randomPassword = randomPasswordSupplier.get();

Is there an equivalent of this interface in C#?

Orace
  • 7,822
  • 30
  • 45
Roland Weisleder
  • 9,668
  • 7
  • 37
  • 59
  • 7
    [`Func`](https://learn.microsoft.com/en-us/dotnet/api/system.func-1) – madreflection Jan 11 '22 at 10:14
  • 1
    also relevant Consumer -> Action: https://stackoverflow.com/questions/36449343/what-is-the-c-sharp-equivalent-of-java-8-java-util-function-consumer – Isitar Jan 11 '22 at 10:17

3 Answers3

5

In C# (and maybe other languages) this is a delegate, a delegate is a reference to methods with a particular parameter list and return type

a type that represents references to methods with a particular parameter list and return type

You can define your own delegates like so:

public delegate int Answer();

(This often used when declaring event handlers)

Alone this does nothing, but you can then use it like any other type to pass references to methods around, like so

public void PrintAnswer(Answer theAnswer)
{
    Console.WriteLine(theAnswer());
    // If 'theAnswer' can be null, then you can check for it normally, or use the Invoke method like so
    Console.WriteLine(theAnswer?.Invoke());
}

For convenience .NET includes some pre defined delegate types, namely Action which is a method with no return value (void) and an arbitrary amount of parameters (max 16), Func which is a method with a return type and an arbitrary amount of parameters (up to 16) and last but not least Predicate which is a method that returns a boolean and has exactly one parameter (so shorthand for Func<T, bool>)

In your case, you'll want to use Func<string> like so:

Func<string> randomPasswordProvider = () => "sekrit";
var randomPassword = randomPasswordProvider(); // or .Invoke()

Note that in C# we use a fat arrow (=>) for anonymous methods. You could also make the randomPasswordProvider point to a "full fat" method like so:

string GenerateRandomPassword()
{
    return "Hello world";
}

// Note the lack of '()', we're not invoking the method, only referencing it
Func<string> randomPasswordProvider = GenerateRandomPassword;

If you want to name your delegate type, you can easily do it like so:

public delegate string StringSupplier(); // any name you want

// or, if you want to have it generic:

public delegate T Supplier<out T>(); // the 'out' is not needed but helpful

I made an example here

You could then add also add an extension method to your custom delegate type so you can call Get() instead of Invoke() or just () (but this really isn't necessary, just makes it look more like your Java example)

MindSwipe
  • 7,193
  • 24
  • 47
1

Any generic delegate with the "take no argument, return T" signature will work.
You can define yours:

public delegate T Supplier<out T>(); // out is not mandatory but is helpfull

Or use System.Func<TResult> which is declared in the standard library.

To call it, you just use the () operator:

// Func<string> randomPasswordSupplier = () => "secret";
Supplier<string> randomPasswordSupplier = () => "secret";
stringrandomPassword = randomPasswordSupplier();
Orace
  • 7,822
  • 30
  • 45
1

As madreflection already noted in a comment, the equivalent is for most cases Func<TResult>. C# doesn't use interfaces for this, but delegates, which are effectively the signature of a method.

You can also create your own delegate that does the same:

public delegate TResult Supplier<TResult>();

This would allow you to include specific documentation for example, where the generic Func delegate would be confusing.

Joey
  • 344,408
  • 85
  • 689
  • 683