C#中与java.util.function.Supplier相对应的是什么?

5
在Java中,Supplier接口代表一个没有参数但具有通用返回值的函数。
Supplier<String> randomPasswordSupplier = () -> "secret";
String randomPassword = randomPasswordSupplier.get();

在C#中有类似的接口吗?


7
Func<TResult>是一个泛型委托类型,它不接受参数并返回一个指定类型的结果。在.NET框架中广泛使用。 - madreflection
1
也相关的消费者 -> 行动: https://dev59.com/BVoV5IYBdhLWcg3wRtLa - Isitar
3个回答

5
在C#(以及其他语言中),这是一个delegate,委托是对具有特定参数列表和返回类型的方法的引用。

代表引用具有特定参数列表和返回类型的方法的类型

您可以像这样定义自己的委托:

public delegate int Answer();

(这通常用于声明事件处理程序)

单独使用它并没有什么作用,但您可以像使用其他类型一样使用它来传递方法的引用,例如:

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());
}

为了方便起见,.NET包括一些预定义的委托类型,即Action,它是一个没有返回值(void)和任意数量参数(最多16个)的方法,Func,它是一个带有返回类型和任意数量参数(最多16个)的方法,最后Predicate,它是一个返回布尔值并且只有一个参数的方法(因此是Func<T, bool>的简写)。
在您的情况下,您将需要使用Func<string>,如下所示:
Func<string> randomPasswordProvider = () => "sekrit";
var randomPassword = randomPasswordProvider(); // or .Invoke()

请注意,在C#中,我们使用一个“胖箭头”(=>)表示匿名方法。您也可以将randomPasswordProvider指向一个“完整的胖方法”,如下所示:
string GenerateRandomPassword()
{
    return "Hello world";
}

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

如果你想为你的委托类型取名,你可以像下面这样轻松地完成:
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

我做了一个例子在这里
你可以为自定义委托类型添加扩展方法,这样你就可以调用Get()而不是Invoke()()(但这并不是必需的,只是让它看起来更像你的Java示例)。

1
任何具有“不带参数,返回T”的签名的通用代理(delegate)都可以使用。
您可以定义自己的:
public delegate T Supplier<out T>(); // out is not mandatory but is helpfull

或者使用标准库中声明的 System.Func<TResult>
调用它时,只需使用 () 运算符:
// Func<string> randomPasswordSupplier = () => "secret";
Supplier<string> randomPasswordSupplier = () => "secret";
stringrandomPassword = randomPasswordSupplier();

1
正如 madreflection 在评论中已经指出的那样,对于大多数情况来说,其等价物是Func<TResult>。C#不使用接口来实现这一点,而是使用委托,它们有效地是方法的签名。
您也可以创建自己的委托来实现同样的功能:
public delegate TResult Supplier<TResult>();

这将使您能够包含特定的文档,例如,在通用的Func委托会令人困惑的情况下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接