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委托类型必须返回一个值。使用