在谈到lambda表达式之前,首先要说一下委托,在下一章会详细介绍委托,在这里就是简单说明一下。

委托的关键字段delegate,声明委托

        public delegate void NoReturnNoPara();//1 委托的声明
public delegate int WithReturnNoPara();
public delegate void NoReturnWithPara(int id, string name);
public delegate LambdaShow WithReturnWithPara(DateTime time);

可以这样说吧,委托就好比于在C语言中的函数指针。

在这里先声明一个无返回值的DoNothing方法

        private void DoNothing(int id, string name)
{
Console.WriteLine("{0} {1} DoNothing out",id,name);
}

要使用委托必须方法签名相一致。

在框架1.0时代。

                NoReturnWithPara method = new NoReturnWithPara(this.DoNothing);//2 委托的实例化
method.Invoke(1, "ming");//3 委托的调用
method(2, "22");
 method.Invoke(1, "ming");和 method(2, "22");效果是一样的。
后来随着版本的升级,又发生了一点变化,可以把new对象给省略。
                NoReturnWithPara method = this.DoNothing;
method.Invoke(2, "jia");

 但是这样的写法,微软爸爸又觉得这样写不太方便,因为这样写需要提前准备个DoNothing方法,所以微软做了个大的修改,这回改的居然可以把DoNothing也省略,这就很方便了,没记错的话这应该是发生在框架3.0时代

                    NoReturnWithPara method = new NoReturnWithPara(
delegate(int id, string name)//把方法的声明改成了使用delegate关键字
{ Console.WriteLine("{0} {1} DoNothing",id,name);
});
method.Invoke(3, "yy");

  这样写已经很便利了吧,但是“懒才是社会进步的动力”,为了偷懒,微软居然把delegate关键字也省略,改为=>(goes to)。

               NoReturnWithPara method = new NoReturnWithPara(
(int id, string name) =>//goes to
//lambda表达式:是一个匿名方法,是一个方法
{
Console.WriteLine(nameOut);
Console.WriteLine("{0} {1} DoNothing");
});
method.Invoke(4, "N");

  已经到达这样了,但是人类还是不满足,后来索性把参数类型也省略,因为你要是这个委托,那肯定必须满足委托的参数类型

                NoReturnWithPara method = new NoReturnWithPara(
(id, name) =>
//去掉参数类型,原因是委托的约束
{
Console.WriteLine("{0} {1} DoNothing",id,name);
});
method.Invoke(5, "小小");

  都到这个地步了,我们还是可以偷偷懒的,只是需要满足几个条件。

1)如果方法体只有一行,那么可以去掉大括号和分号,多行不行
2)如果参数只有一个 可以去掉小括号
3)如果没有参数,直接用小括号

            {
NoReturnWithPara method = new NoReturnWithPara((id, name) => Console.WriteLine("{0} {1} DoNothing", id, name));
method.Invoke(6, "分");
}

那么什么是 匿名类 和var关键字。

                  var model = new
{
Id = 1,
Name = " Go",
Age = 21,
ClassId = 2
};
Console.WriteLine(model.Id);
Console.WriteLine(model.Name);

var:它主要用于在声明变量时,无法确定数据类型时使用

就好比这个model,他的类型是不确定的,这就可以声明匿名类。

再来讲讲系统自带委托Action/Func。

Action是无返回值类型的委托,Func是带有返回值类型的委托。

                Action act1 = () => Console.WriteLine("1234");
Action<int> act2 = t => { };
                Func<int> func1 = () => 1;
int i = func1();
Func<int, string> func2 = t => "1234";

什么是拓展方法呢。在这里我就不讲官方的语言了,就讲讲我的认识吧,其实拓展方法在我看来就是一些静态方法,在你调用这个方法时,不需要去创建一个对象,直接可以调用。

那么怎么去创建一个拓展方法呢,其实很简单,主要是声明一个静态类,在静态类里面声明一个静态方法,方法的第一个参数声明一个对象,注意第一个参数类型前面加上this

        public static void NoShow(this LambdaShow show)
{
Console.WriteLine("这里是扩展的 NoShow");
}
                    LambdaShow show = new LambdaShow();
show.Show();
show.NoShow();

那万一类方法中有一个show方法,而拓展方法里面也有一个show方法,那通过show.Show();调用是调用类里面的方法还是拓展里面的方法呢?答案是类中的方法。

接下来再来谈谈linq。在这里我就简单的说下linq几个常用的方法吧。

创建一个student实体类

 public class Student
{ public int Id { get; set; }
public int ClassId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

初始化实体类,并添加一些数据。

 private List<Student> GetStudentList()
{ List<Student> studentList = new List<Student>()
{
new Student()
{
Id=1,
Name="猎人",
ClassId=2,
Age=35
},
new Student()
{
Id=1,
Name=" Go",
ClassId=2,
Age=23
},
new Student()
{
Id=1,
Name="水",
ClassId=2,
Age=27
},
new Student()
{
Id=1,
Name="明",
ClassId=2,
Age=26
}
}

在这里提出一个需求,筛选出年龄大于25岁的同学。

如果不适用linq只使用普通方法,大概是思路是先创建一个student的list对象,然后再把实体对象遍历判断条件,条件满足的添加到list集合中。

            List<Student> studentList = this.GetStudentList();

            List<Student> studentListlessThan25 = new List<Student>();
foreach (var item in studentList)
{
if (item.Age < 25)
{
studentListlessThan25.Add(item);
}
}

而如果我们使用Linq呢

               var list = studentList.Where<Student>(s => s.Age < 25);
foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.Name, item.Age);
}

如果你熟悉的话,这样看语句就跟看陈述句一样简单明了。

那么我们不经要问,框架的where函数里面封装了哪些方法呢,让我们使用起来这么简单。通过反编译工具,其实里面的方法很简单

模仿者框架中的where方法,试着自己写了一个方法。

 public static IEnumerable<TSource> XiMaWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> func)
{
List<TSource> studentList = new List<TSource>();
foreach (TSource item in source)
{
bool bResult=func.Invoke(item);
if (bResult)
{
studentList.Add(item);
}
}
return studentList;
}

这就是where方法里面主要的一些内容

然后我们可以跟where方法一样使用

               var list = studentList.XiMaWhere<Student>(s => s.Age < 25);//陈述句

                foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.Name, item.Age);
}

是不是很强大!!!

还有一些linq语句,这里就简单带过一下,有兴趣的可以自己去查阅资料

               Console.WriteLine("********************");
var list = from s in studentList
where s.Age < 25
select s; foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.Name, item.Age);
}

  

Lambda(Linq)的更多相关文章

  1. 【C#进阶】拥抱Lambda(二)

    语言的设计,真的是挺有意思的.第一次看这个代码[1]时,旁人随口了一句"哇,好多实心句号". 当时马上一个想法是--怎么实现的?返回了对象,然后再调用方法?然后就放下了,后来发现, ...

  2. filter,map,reduce,lambda(python3)

    1.filter filter(function,sequence) 对sequence中的item依次执行function(item),将执行的结果为True(符合函数判断)的item组成一个lis ...

  3. 【C#进阶】拥抱Lambda(一)

    写在开头,好奇从这里开始(当时让加查询条件,结果竟然是一句话来发挥神奇作用): this.TestGrade = CriteriaHelper.NewObject<ITestCase, DtoT ...

  4. 实战 EF(LINQ) 如何以子查询的形式来 Join

    如题,大多数网上关于 LINQ Join 的示例都是以 from x in TableA  join ... 这样的形式,这种有好处,也有劣势,就是在比如我们使用的框架如果已经封装了很多方法,比如分页 ...

  5. 函数编程——匿名函数与lambda(一)

    python允许用lambda关键字创造匿名函数. 匿名函数是因为不需要以标准的方式来声明,比如说,使用def语句. 但是,作为函数,它们也能有参数. 一个完整的lambda“语句”代表了一个表达式, ...

  6. java 基本语法(十六)Lambda (三)函数式接口

    方法引用1.理解:方法引用可以看做是Lambda表达式深层次的表达.换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法. 2.使用情境:当要传递给Lam ...

  7. java 基本语法(十四)Lambda (一)表达式

    1.Lambda表达式使用前后的对比:举例一: @Test public void test1(){ Runnable r1 = new Runnable() { @Override public v ...

  8. 第十讲(LINQ)

    一..LINQ查询 例如: static void LINQQuery() { var query = from r in Formula1.GetChampions() where r.Countr ...

  9. Lambda(2)

    Lambda表达式是匿名方法的超集,处理匿名方法有的功能外,还有其他的功能: 1.能够推测出参数的类型,无需显示声明 2.支持语句块和表达式作为方法体 Lambda表达式的书写方式: Lambda表达 ...

随机推荐

  1. Netflix Hystrix - 快速入门

    Hystrix最初是由Netflix的API team研发的,用于提高API的弹性和性能,2012年在公司内部广受好评. 如果你的应用是一个单独的应用,那几乎不用在意断路的问题. 但在分布式环境中,各 ...

  2. ng-checked选择和点击增加dom

      1.需求 在添加页面实现一个checkbox的选择,然后在详情页面展示时,会自动选上之前被选中的. 2.添加页面 看官最好将这个代码复制过去看看效果. <!DOCTYPE html>& ...

  3. MyBatis源码解读(1)——SqlSessionFactory

    在前面对MyBatis稍微有点了解过后,现在来对MyBatis的源码试着解读一下,并不是解析,暂时定为解读.所有对MyBatis解读均是基于MyBatis-3.4.1,官网中文文档:http://ww ...

  4. js实用方法记录-简单cookie操作

    js实用方法记录-简单cookie操作 设置cookie:setCookie(名称,值,保存时间,保存域); 获取cookie:setCookie(名称); 移除cookie:setCookie(名称 ...

  5. Android开发中使用static变量应该注意的问题

    package com.highxin.launcher01; import java.util.ArrayList; import java.util.HashMap; import java.ut ...

  6. Django集成celery实战小项目

    上一篇已经介绍了celery的基本知识,本篇以一个小项目为例,详细说明django框架如何集成celery进行开发. 本系列文章的开发环境: window 7 + python2.7 + pychar ...

  7. 8611 大牛之路I

    #include<stdio.h> ]; int main() { int i, n, m, sum, x, y; scanf("%d%d", &n, & ...

  8. PHP 关于timezone问题

    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use ...

  9. Introducing: Machine Learning in R(转)

    Machine learning is a branch in computer science that studies the design of algorithms that can lear ...

  10. The leaflet package for online mapping in R(转)

    It has been possible for some years to launch a web map from within R. A number of packages for doin ...