.Net中有一个内置的委托 Func

它总共有以下5种形式

1.  Func<TResult>

2.  Func<T,TResult>

3.  Func<T1,T2,TResult>

4.  Func<T1,T2,T3,TResult>

5.  Func<T1,T2,T3,T4,TResult>

上面5种形式,第1种 Func<TResult> 没有参数,只有返回值

我们来看一个例子

private delegate string MyDelegate();

public static string OutputDelegate()
{
return "Test delegate";
} public static void Main(string[] args)
{
MyDelegate testFunc = OutputDelegate; Console.WriteLine(testFunc()); // 输出 Test delegate }

在这个例子中,我们自己定义了一个委托MyDelegate. 但是 上面我们也说了,.Net中有自己内置的委托,或者说是.Net中默认自带的委托, 我们来看看如何使用.Net自带的委托 Func<TResult>

public static string OutputDelegate()
{
return "Test delegate";
} public static void Main(string[] args)
{
Func<string> testFunc = OutputDelegate; Console.WriteLine(testFunc()); // 输出 Test delegate }

在上面,我们使用了.net自带的委托的第一种类型Func<TResult>, 这个委托没有参数传入,返回值类型为TResult. 由于上面OutputDelegate方法中返回string类型,所以对应委托就是Func<string>

如果有参数呢,我们就需要使用其他4种形式了。 我们来看一看第2种形式委托Func<T,TResult>的使用

public static string OutputDelegate(string testStr)
{
return testStr + testStr;
} public static void Main(string[] args)
{
Func<string,string> testFunc = OutputDelegate; string strResult = testFunc("test"); Console.WriteLine(strResult); // 输出 test test }

上面的.Net内置委托Func也支持Lambda的形式调用, 我们来看一个例子

Func<string,string> myDelegate = x => x + x;

Console.WriteLine(myDelegate("test")); // 输出 testtest

我们现在属性了这个内置委托Func,那么它一般在哪里使用呢,或者说在什么场景下使用比较多呢

事实上,在编程过程中,它使用最多的场景是作为函数的参数,比如下面这样

string GetResult(Func<string,string>)

在这个方法中,参数是一个代理,我们通常会通过传入一个Lambda表达式,这个代理输入参数是string类型,而返回值也是string类型,所以你看GetResult函数的返回类型就是string类型

我们知道,Linq查询操作中有一些聚合函数(count,max,min,sum,average,aggregate,longcount),我们来看看其中count的原型

public static int Count<TSource>(this IEnumerable<TSource> source);
public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource,bool> predicate);

我们从上面看到,Linq中的Count聚合函数有两个原型,第一个就是单独的计算序列中的元素的数量总和。  而第2个原型有一个委托函数,用来筛选满足一定条件的元素,然后再计算满足条件的数量和. 我们来看个实现它们的例子

private void GetCount()
{
int[] intList = new int[] {,,,,,,}; var countResult = intList.Count() //输出 7
var countResult2 = intList.Count(x=>x > ) //输出 2 }

我们再来看看其中的sum函数的一个原型

public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource,int> selector);

看完这些,有没有啥感觉,有没有发现自己也可以写一个Linq的聚合函数,使用类似它默认自带的聚合函数同样的方法,使用扩展方法,委托作为参数,我们自己来试试, 取名为MyLinqFunc

public static TSource MyLinqFunc(this IEnumerable<TSource> source, Func<TSource, bool> funcCondition)
{
foreach(TSource item in source)
{ if(funcCondition(item))
{
return (item);
} } throw new Exception("没有满足条件的元素"); }

现在我们来写一个例子,可以使用这个自己定义的Linq的聚合函数

class myClass
{
static void Main(string[] args)
{
List<int> intList = new List<int>(){,,,,,,,};
int result = intList.MyLinqFunc(t=>t < ); //输出 1 这里使用上面我们自己定义的Linq聚合函数 MyLinqFunc
Console.WriteLine(result); } }

看了上面的分析后,我们再去看msdn上关于Enumerable.Select<TSource,TResult>方法,就更容易理解,可以自己去看https://msdn.microsoft.com/zh-cn/library/bb548891(v=vs.110).aspx   https://msdn.microsoft.com/zh-cn/library/bb534869(v=vs.110).aspx

上面我们讨论了.Net中的泛型委托,我们知道,还有一个概念,就是委托表达式,这样一种形式Expression<Func<TSource,TResult>>. 那么这两者到底有什么区别呢。这是一个很容易让人摸不清头脑的问题

我们来看看

Func<TSource,TResult> 是委托

Expression<Func<TSource,TResult>>是表达式

Expression要编译后(调用Expression的Compile方法)才能变成delegate, 才能运行。 举个例子如下

Expression<Func<int,bool>> ex = x => x > ;
Func<int,bool> myFunc = ex.Compile();

现在我们就可以调用myFunc:

myFunc(5)  //返回false

myFunc(12) //返回true

而表达式是不可以直接调用的

但是在Linq to Entity的Where查询条件中,就应该使用Expression,而不是使用委托。 比如如下是错误的

Func<tbUser,bool> existFunc = u => u.userID == id && u.userName == name;

_tbUserRepository.Entities.Where(existFunc);

上面这里,where里面的参数是一个委托,这个是错误的。实际上,where里面需要的参数是Expression, 所以正确的方式应该如下

Expression<Func<tbUser,bool>> existFunc = u => u.userID == id && u.userName == name;

_tbUserRepository.Entities.Where(existFunc);

.NET中的泛型委托的更多相关文章

  1. List<string>中的泛型委托

    我们先看List<T>.Sort().其定义是:public void Sort( Comparison<T> comparison ) 其要求传入的参数是Comparison ...

  2. 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

    引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...

  3. .NET中的Action及Func泛型委托

    委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调机制的实现基 ...

  4. 使用.NET中的Action及Func泛型委托

          委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调 ...

  5. C#中Predicate<T>与Func<T, bool>泛型委托的用法实例

    本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用.具体如下: 先来看看下面的例子: 1 2 3 4 5 6 ...

  6. 泛型委托及委托中所涉及到匿名方法、Lambda表达式

    泛型委托及委托中所涉及到匿名方法.Lambda表达式 引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到 ...

  7. c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对

    首先要引用一下类库:using Ionic.Zip;这个类库可以到网上下载. 下面对类库使用的封装方法: 得到指定的输入流的ZIP压缩流对象 /// <summary> /// 得到指定的 ...

  8. C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法

    使用C#实现加减乘除算法经常被用作新手练习.本篇来分别体验通过委托.接口.匿名方法.泛型委托来实现. 使用委托实现 加减乘除拥有相同的参数个数.类型和返回类型,首先想到了使用委托实现. //创建一个委 ...

  9. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

随机推荐

  1. SDUT 1048 Digital Roots

    Digital Roots Time Limit: 1000ms   Memory limit: 65536K 题目描述 The digital root of a positive integer ...

  2. Luogu-2600 [ZJOI2008]瞭望塔

    把地面看成半平面,能看到所有位置的点所在的区域即为半平面的交 因为分段函数的极值只会在转折处或边界取到,所以对于半平面上和地面上的每一个交点都求一下距离就好了 #include<cmath> ...

  3. O(1) 快速乘

    有一些毒瘤题,数据大小不光会炸\(int\),有时甚至会炸\(long long\).这时一个\(O(1)\)的防爆乘就很重要了 \(a*b%p\)可以转化为\(a*b-[a*b/p]*p\) 这里用 ...

  4. Windows 2003 复制大文件提示系统资源不足的处理方法

    方案一: 修改虚拟内存,让虚拟内存的大小略微超过要复制的文件的大小. 方案二: 修改注册表,如下: 注册表设置1 单击开始,单击运行,在打开框中键入“REGEDIT“ ,然后单击“确定”. 找到并单击 ...

  5. 算法(Algorithms)第4版 练习 1.5.8

    假设原id数组: 0 1 1 4 4 8 6 1 8 0 输入p = 5, q = 7 则输出结果会出错,最终为: 0 1 1 4 4 1 6 1 8 0 因为当id[p](id[5] = 8)被赋值 ...

  6. ML三(人工神经网络)

    人工神经网络 Artificial Neural Nerworks 基本术语概念: 人工神经网络(Artificial Neural Networks,ANN) 感知器(Perceptron):以一个 ...

  7. Spark- 流量日志分析

    日志生成 package zx.Utils import java.io.{File, FileWriter} import java.util.Calendar import org.apache. ...

  8. 使用jQuery为博客生成目录

    这段代码展示了如何为div#content中的内容生成目录,也无非是对h系列标记进行解析.当然,也早有一些人实现了.​1. [代码][HTML]代码     <html>    <h ...

  9. KbmMW-及相关

    KbmMW框架是收费的,不在此提供下载,如需购买,请自行联系作者Kim Madsen. 网址资源: 官网主页:http://www.components4programmers.com/product ...

  10. thinkphp微信开发(消息加密解密)

    使用thinkphp官方的WeChat包,使用不同模式可以成功,但是安全模式就是不行,现将分析解决结果做下记录. 分析问题: 解密微信服务器消息老是不成功,下载下微信公众平台官方给出的解密文件和Wec ...