曾经我们为了可以调用一个方法。必须比照这种方法定义一个对应的delegate.

原先我们定义delegate

// 托付声明 -- 定义一个签名:
delegate double MathAction(double num);
class DelegateTest
{
// 符合托付声明的常规方法
static double Double(double input)
{
return input * 2;
} static void Main()
{
原版: // 使用一个命名方法实例化托付类型
MathAction ma = Double; // 调用托付实例
double multByTwo = ma(4.5);
Console.WriteLine(multByTwo); 简化版1: // 再用匿名方法来实例化托付类型
MathAction ma2 = delegate(double input)
{
return input * input;
}; double square = ma2(5);
Console.WriteLine(square); 简化版2: // 最后用Lambda表达式来实例化托付类型
MathAction ma3 = s => s * s * s;
double cube = ma3(4.375); Console.WriteLine(cube);
}
}

这个能否有更好的实现办法呢?

答案是:肯定有了.也就是有通用的delegate了。

在.NETFramework
3.5中。提供了两类通用的delegate。

假设方法有返回值,则使用Func,或者Func<>

假设方法没有返回值,则使用Action,或者Action<>

Func<T,TR>(T arg)

參数类型

T

此托付封装的方法的參数类型。

TR

此托付封装的方法的返回值类型。

參数

arg
类型 T

此托付封装的方法的參数。

在使用 Func<T,TResult>托付时,不必显式定义一个封装仅仅有一个參数的方法的托付。下面演示样例简化了此代码,它所用的方法是实例化
Func<T, TResult>托付,而不是显式定义一个新托付并将命名方法分配给该托付。

使Func<>托付,我们这样写

using System;

public classLambdaExpression
{
public static void Main()
{
Func<string, string> convert = s=> s.ToUpper();//该方法将小写字母转为大写
string name = "Dakota";
Console.WriteLine(convert(name));
}
}

Func托付是system下的全局函数,不用我们自定,系统自己定义的,供我们使用,带有多个重载.

这里我们除了使用Func托付外,还是用了Labdab表达式.这里我再谈谈这个表达式.

Lambda表达式的基础类型是泛型 Func托付之中的一个。 这样能以參数形式传递
lambda表达式,而不用显式将其分配给托付。

尤其是,由于 System.Linq命名空间中很多类型方法具有Func<T,
TResult>參数,因此能够给这些方法传递 lambda表达式。而不用显式实例化
Func<T, TResult>托付。

以下一行代码将生成一个序列,当中包括 numbers 数组中在
9左側的全部元素。由于它是序列中第一个不满足条件的数字:

int[] n= { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

实例2

var firstSmallNumbers =numbers.TakeWhile((n, index) => n >= index);

此演示样例展示了怎样通过将输入參数括在括号里来指定多个输入參数。该方法将返回数字数组中的全部元素,直至遇到一个值小于其位置的数字为止。不要将
lambda运算符 (=>)与大于等于运算符 (>=)混淆。

三种托付写法对照

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace func
{
//托付声明 -- 定义一个签名:
delegate double MathAction(double num);
public class Program
{
// 符合托付声明的常规方法
static double Double(double input)
{
return input * 2;
} static void Main(string[] args)
{
// 使用一个命名方法实例化托付类型
/*
* 写法一,须要写出专门托付的函数,还须要自己定义托付
**/
MathAction ma = Double;//注意这里千万不可有Double(),否则就成了一个返回类型。是报错的,这里是制定函数的地址,给定的是函数的地址 //调用托付
double result1 = ma(4.5); //使用系统自己定义托付实例化托付类型
/*
* 写法二。须要写出专门托付的函数。不须要自己定义托付。使用系统托付
**/
Func<double,double> func = Double; //调用托付
double result2 = func(4.5); //系统托付使用lamdba进行传递參数
/*
* 写法三。不须要写出专门托付的函数。还须要自己定义托付
**/
Func<double, double> result = s=> s * 2;//写法还能够换成lamdba语句块,适应多个參数的写法 double result3=result(4.5); Func<double,double> result4 = s =>
{
return s * 2;
}; Console.WriteLine(result1);
Console.WriteLine(result3);
Console.WriteLine(result2);
Console.WriteLine(result4(4.5));
}
} }

效果图

相同的输出效果,可是编写代码的质量确有不同。当然了也是要对自己的问题进行负责的。lamdba的使用简化的代码。可是假设自己不是对这个非常熟悉,非常easy造成出现故障,如从着手错误的源泉。匿名函数的写法解决的这个问题。可是匿名函数却没有Lamdba简便。这就是折中方法吧。看自己更喜欢哪种了。

小结:

从Func的托付中。我们能够看出,它简化了我们自定义托付带来的繁琐。同一时候它更好的结合了Lamdba的使用。降低了自定义函数的作用。同一时候也是有缺点的,就是错误的出现不easy发现是那里。

Action托付的使用与Func雷同。这里就不在说了。希望自己的总结能够对大家有所帮助。

C# Func&lt;&gt;托付的更多相关文章

  1. 6.5.2 C# 中的函数组合

    6.5.2 C# 中的函数组合 C# 中的函数组合是可能的.但使用非常有限,这是部分是由于在 C# 中散应用不能非常easy使用.但更重要的是,由于大多数操作是用成员来写的.而不是函数.但我们至少能够 ...

  2. c#Lamdba表达式与托付

    介绍: "Lambda表达式"(lambda expression)是一个匿名函数,在C#3.0中引入了lambda表达式,它是对匿名函数的一种简化,能够包括表达式和语句,而且可用 ...

  3. 浅析C#中的托付

    托付是寻址方法的.NET版本号.在C++中.函数指针仅仅只是是一个指向内存位置的指针,它不是类型安全的.而.NET托付全然不同,托付是安全类型的类,它定义了返回类型和參数的类型. 当把方法传递给其它方 ...

  4. C#托付之愚见

    C#托付起源 近期參加实习和奔走于各大招聘会,被问及非常多技术方面的问题.C#问的较多的就是托付和linq. linq之前已经写过一篇文章,能够參见 http://blog.csdn.net/yzys ...

  5. C#基础知识六之委托(delegate、Action、Func、predicate)

    1. 什么是委托 官方解释 委托是定义方法签名的类型,当实例化委托时,您可以将其实例化与任何具有兼容签名的方法想关联,可以通过委托实例调用方法. 个人理解 委托通俗一点说就是把一件事情交给别人来帮助完 ...

  6. C#委托的介绍(delegate、Action、Func、predicate)

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 (1). delegate delegate我们常用到的一种声明   Deleg ...

  7. winform总结2> Action<> ,Action,func<>,委托相关的理解

    1,他们是什么: Action 封装一个方法,该方法不具有参数并且不返回值. Action<> 封装一个方法,该方法具有最多16个参数并且不返回值. func<> 封装一个具有 ...

  8. Func

    Func<List<int>, string> getStr = (list) => { var returnStr = ""; if (list.A ...

  9. 浅谈C#中常见的委托<Func,Action,Predicate>(转)

    一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的. 关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微,尤其是张子阳的那一篇.我就不 ...

随机推荐

  1. ECshop 二次开发模板教程2

    不知道大家是学会用循环了呢,还是我的言语实在有问题,大家实在无法完成阅读哦,居然大家都没有问题,暂时心里安慰,把他当做好事情,大家都会调用了,呵呵,那我们继续循环调用商品了!好,继续在我们昨天的基础上 ...

  2. HDU 5734 Acperience

    Acperience Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  3. C#网络资源列表

    1, http://club.topsage.com/thread-371996-1-1.html

  4. Redis源码分析系列

    0.前言 Redis目前热门NoSQL内存数据库,代码量不是很大,本系列是本人阅读Redis源码时记录的笔记,由于时间仓促和水平有限,文中难免会有错误之处,欢迎读者指出,共同学习进步,本文使用的Red ...

  5. IOS 屏幕截图 UIScrollview

    //截图UIView:截全图 -(UIImage*)captureView:(UIView *)theView{ CGRect rect = theView.frame; if ([theView i ...

  6. bzoj 1109 [POI2007]堆积木Klo(LIS)

    [题意] n个数的序列,删除一个数后序列左移,求最后满足i==a[i]的最大个数. [思路] 设最终得到a[i]==i的序列为s,则s应满足: i<j,a[i]<a[j],i-a[i]&l ...

  7. Tkinter教程之Button篇(2)

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1811300 # Tkinter教程之Button篇(2)'''5.指定Button的宽度与高度 ...

  8. Selection sort

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  9. linux高级数据存储

    linux内此存储模式由5部分组成,自低向上的顺序: 物理卷,内核块设备驱动,内核文件系统驱动,虚拟文件系统,应用程序数据结构; 系统中所有的文件仅按此模式存储,无论是数据还是元数据,均在此模式下统一 ...

  10. Apache Spark GraphX

    GraphX基于BSP模型,在Spark之上封装类似Pregel的接口,进行大规模同步全局的图计算,尤其是当用户进行多轮迭代时,基于Spark内存计算的优势尤为明显.