Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么是Func,如何以及何时使用_C#_.net_Delegates - Fatal编程技术网

C# 什么是Func,如何以及何时使用

C# 什么是Func,如何以及何时使用,c#,.net,delegates,C#,.net,Delegates,什么是Func及其用途?Func是一种预定义的委托类型,用于返回类型为T的值的方法 换句话说,您可以使用此类型引用一个方法,该方法返回T的某个值。例如 public static string GetMessage() { return "Hello world"; } 可以这样引用 Func<string> f = GetMessage; Func f=GetMessage; Func和其他预定义的泛型Func委托(Func、Func和其他)是返回最后一个泛型参数类型的泛型委托

什么是
Func
及其用途?

Func
是一种预定义的委托类型,用于返回类型为
T
的值的方法

换句话说,您可以使用此类型引用一个方法,该方法返回
T
的某个值。例如

public static string GetMessage() { return "Hello world"; }
可以这样引用

Func<string> f = GetMessage;
Func f=GetMessage;
Func
和其他预定义的泛型
Func
委托(
Func
Func
和其他)是返回最后一个泛型参数类型的泛型委托


如果函数需要返回不同的类型,根据参数的不同,可以使用
Func
委托指定返回类型。

将其视为占位符。当您有遵循特定模式但不需要绑定到任何特定功能的代码时,它可能非常有用

例如,考虑<代码>枚举。选择< /Cord>扩展方法。< /P>

  • 模式是:对于序列中的每个项目,从该项目中选择一些值(例如,属性),并创建由这些值组成的新序列
  • 占位符是:一些选择器函数,它实际获取上述序列的值
此方法采用
Func
而不是任何具体函数。这允许在上述模式适用的任何上下文中使用它

例如,假设我有一个
列表
,我只想要列表中每个人的名字。我可以这样做:

var names = people.Select(p => p.Name);
或者说我想要每个人的年龄:

var ages = people.Select(p => p.Age);
现在,您可以看到我是如何利用表示模式的相同代码(使用
Select
)和两个不同的函数(
p=>p.Name
p=>p.Age
)的

另一种方法是,每当您希望扫描序列以获取不同类型的值时,编写不同版本的
Select
。因此,要达到上述效果,我需要:

// Presumably, the code inside these two methods would look almost identical;
// the only difference would be the part that actually selects a value
// based on a Person.
var names = GetPersonNames(people);
var ages = GetPersonAges(people);
有了代理作为占位符,我就不必在这种情况下反复写出相同的模式了。

Func
表示一个函数,它接受(T1,T2,…,Tn)参数并返回Tr

例如,如果您有一个函数:

double sqr(double x) { return x * x; }
您可以将其另存为某种函数变量:

Func<double, double> f1 = sqr;
Func<double, double> f2 = x => x * x;
等等


但请记住,它是一个委托,有关更高级的信息,请参阅文档。

它只是一个预定义的通用委托。使用它,您不需要声明每个委托。还有另一个预定义的委托,
Action
,该委托相同,但返回void。

我发现在创建需要“动态”个性化的组件时,
Func
非常有用

举一个非常简单的例子:一个
PrintListToConsole
组件

一个非常简单的对象,将此对象列表打印到控制台。 您希望让使用它的开发人员对输出进行个性化设置

例如,您想让他定义一种特定类型的数字格式,等等

不带函数

首先,您必须为类创建一个接口,该类接受输入并生成要打印到控制台的字符串

interface PrintListConsoleRender<T> {
  String Render(T input);
}
class Program {
    static void Main(string[] args) {
        var list = new List<int> { 1, 2, 3 }; // should be a list as the method signature expects
        var printer = new PrintListToConsole<int>();
        printer.SetRenderFunc((o) => "Number:" + o);
        printer.Print(list); 
        string result = Console.ReadLine();
    }
}
使用Func更简单

在组件内部,您定义一个
Func
类型的参数,该参数表示一个函数的接口,该函数接受T类型的输入参数并返回一个字符串(控制台的输出)

类PrintListToConsole{
私有函数(renderFunc);;
公共void SetRenderFunc(函数r){
//这是我可以设置渲染机制的点
_renderFunc=r;
}
公共作废打印(列表){
foreach(列表中的变量项){
Console.Write(_renderFunc(项目));
}
}
}
当开发人员使用您的组件时,他只需将
Func
类型的实现传递给组件,这是一个为控制台创建输出的函数

interface PrintListConsoleRender<T> {
  String Render(T input);
}
class Program {
    static void Main(string[] args) {
        var list = new List<int> { 1, 2, 3 }; // should be a list as the method signature expects
        var printer = new PrintListToConsole<int>();
        printer.SetRenderFunc((o) => "Number:" + o);
        printer.Print(list); 
        string result = Console.ReadLine();
    }
}
类程序{
静态void Main(字符串[]参数){
var list=new list{1,2,3};//应该是方法签名所期望的列表
var printer=new PrintListToConsole();
打印机.SetRenderFunc((o)=>“编号:”+o);
打印机。打印(列表);
字符串结果=Console.ReadLine();
}
}
Func
允许您动态定义通用方法接口。
定义输入的类型和输出的类型。
简单明了。

也许现在添加一些信息还不算太晚

总和:

Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
public delegate TResult Func<in T, out TResult>(T arg);
Func是在系统命名空间中定义的自定义委托,它允许您使用0到16个输入参数指向具有相同签名(与委托相同)的方法,并且必须返回某些内容

术语和用法:

Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
public delegate TResult Func<in T, out TResult>(T arg);
Func funcDelegate=someMethod;
定义:

Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
public delegate TResult Func<in T, out TResult>(T arg);
public委托TResult Func(T参数);
使用位置:

Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
public delegate TResult Func<in T, out TResult>(T arg);
它用于lambda表达式和匿名方法。

C#和Java都没有普通函数,只有成员函数(aka方法)。方法也不是一等公民。一流的函数允许我们创建漂亮而强大的代码,如F#或Clojure语言所示。(例如,一级函数可以作为参数传递,也可以返回函数。)Java和C#通过接口/委托在某种程度上改进了这一点

Func<int, int, int> randInt = (n1, n2) => new Random().Next(n1, n2); 
Func randInt=(n1,n2)=>new Random()。下一步(n1,n2);

因此,
Func
是一个内置的委托,它带来了一些函数式编程功能,并有助于减少代码的冗长性。

前面提到的答案很好,只需指出几点可能会有所帮助:

  • Func是内置的委托类型

  • Func委托类型必须返回一个值。使用