委托的实现匿名函数和朗姆达表达式

**委托(delegate):一个表示方法的数据类型。间接派生于System.Delegate

委托是一个引用类型,但不必用new来实例化它。直接传递名称,而不是现实实例化。这是c#2.0开始支持的一个新语法,成为委托推断(delegate inference)

 1 namespace delegateEx
 2 {
 3     //委托声明
 4     public delegate bool ComparisonHandler(int first,int second);
 5
 6     public static class DelegateSample
 7     {   //
 8         public static void BubbleSort(int[] items, ComparisonHandler comparisonMethod)
 9         {
10             int i;
11             int j;
12             int temp;
13             if (items == null)
14             {
15                 return;
16             }
17             if (comparisonMethod == null)
18             {
19                 throw new ArgumentNullException("comparisonMethod");
20             }
21
22             for (i = items.Length - 1; i >= 0; i--)
23             {
24                 for (j = 1; j <= i; j++)
25                 {
26                     //用委托实例
27                     if (comparisonMethod(items[j - 1], items[j]))
28                     {
29                         temp = items[j - 1];
30                         items[j - 1] = items[j];
31                         items[j] = temp;
32                     }
33                 }
34             }
35         }
36         //匹配委托的参数GreaterThan(int first, int second)
37         public static bool GreaterThan(int first, int second)
38         {
39             return first > second;
40         }
41     }
42     class Program
43     {
44         static void Main(string[] args)
45         {
46             int[] items = new int[100];
47             Random random = new Random();
48             for (int i = 0; i < items.Length; i++)
49             {
50                 items[i] = random.Next(1,100);
51             }
52             //将委托实例作为参数传递
53             DelegateSample.BubbleSort(items,DelegateSample.GreaterThan);
54
55             for (int i = 0; i < items.Length; i++)
56             {
57                 Console.Write(" {0}",items[i]);
58             }
59             Console.ReadKey();
60         }
61     }
62 }

**匿名方法:就是没有实际方法声明委托实例,或者说,他们的定义是直接内嵌在代码中的。

 1 static void Main(string[] args)
 2 {
 3     int[] items = new int[5];
 4     Random random = new Random();
 5     ComparisonHandler comparisonMethod;
 6
 7     for (int i = 0; i < items.Length; i++)
 8     {
 9         items[i] = random.Next(1, 100);
10     }
11   //委托的定义直接内嵌在代码中。
12     comparisonMethod = delegate(int first, int second)
13     {
14         return first < second;
15     };
16     BubbleSort(items,comparisonMethod);
17
18     for (int i = 0; i < items.Length; i++)
19     {
20         Console.Write(" {0}", items[i]);
21     }
22     Console.ReadKey();
23 } 

或者使用更直接的方法:

1 BubbleSort(items,
2     delegate(int first, int second)
3 {
4     return first < second;
5 });  

注意,在任何情况下,参数和返回值类型必须兼容于委托的数据类型。

*匿名方法是允许省略参数列表的,但是返回值类型需要与委托一致。

**系统定义的委托:

System.Func 在.NET 3.5中代表有返回类型的委托

System.Action代表无返回类型的委托。

不能将一个委托类型赋给另一个委托类型的变量,即使类型参数匹配。

*为委托使用可变性[还没理解]

Action<object> broadAction=delegate(object data)
{
Console.WriteLine(data);
}
Action<string> narrowAction=broadAction;
Func<string>narrowFunction=delegate()
{
return Console.WriteLine();
};
Func<object> broadFunction=narrowAction;
Func<object ,string >func1=
degate(object data)
{
return data.ToString();
};
Func<string,object>func2=fun1; 

**Lamda表达式 (关键字=>) :分为Lamda表达式和Lamda语句

[csharp] view plaincopy

1 BubbleSort(items,
2                 delegate(int first, int second)
3             {
4                 return first < second;
5             });  

与上述等价的Lamda语句(用于)

1 BubbleSort(items,
2     (int first, int second)=>
3     {
4         return first < second;
5     }
6 ); 

*省略参数类型:通常,只要编译器能推断出参数类型,或者能将参数类型隐式转换成期望的数据类型,语句Lamda就不需要参数类型。如果要制定类型,那么制定的类型必须和委托类型完全匹配。只要Lamda语句包含了一个类型,则所有的类型都要加上。

1 BubbleSort(items,
2     (first,second)=>
3     {
4         return first < second;
5     }
6 );  

*c#要求用一对圆括号来封闭Lamda表达式的参数类表,不管是否指定了这些参数的数据类型。圆括号的另外一个规则是,当编译器能推断出数据类型,而且只有一个输入参数的时候,语句Lamda可以不带圆括号。

Func<string> getUserInput=

()=>

{

string input;;

do

{     input=Console.ReadLine();}

while(input.Trim()==0);

return input;

}

*Lamda表达式(满足……条件)

  1. BubbleSort(items,
  2. (int first, int second)=> first < second );

**Lamda表达式本身没有类型

所以   .    运算符不会被编译,调用Object的方法也不行。

不能出现在is的左侧

Lamda表达式一旦被赋值或者转型,就会有Lamda表达式的类型这种非正式的说法

不能赋值给隐式类型的变量

如果目的在Lamda表达式的外部,c#就不允许在匿名函数内部使用跳转语句(break,continue,goto)

*外部变量:在Lamda表达式(包括参数)的外部声明,但是Lamda表达式的内部捕捉(访问)的局部变量称为外部变量。this也是一个外部变量。

int comparisonCount=0;

...

BubbleSort(item,

(int first ,int second)=>

{

comparisonCount++;

return first<second;

}

);

Console.WriteLine(comparisonCount);

**表达式树[不理解]

“解释”是c#引入表达式树(expression trees)这一概念的重要动机。如果一种Lamda表达式代表的是与表达式有关的数据,而不是编译好的代码,这中Lamda表达式就是表达式树。由于表达式树代表的是数据而非编译好的代码,所以可以把数据转换成一种替代格式。例如,转换成SQL代码。

persons.Where(person=>person.Name.ToUpper()=="INIGO MONTOYA")

select *from Person where upper(Name)=‘INIGO MONTOYA‘

时间: 2024-10-16 01:15:48

委托的实现匿名函数和朗姆达表达式的相关文章

闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别

闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ console.log("named function") } foo() 不过也可以将函数视作数据赋值给变量,这样的函数可以没有名字: nameless = function(){ console.log("anonymouse function") } nameless(

C#基本功------委托和事件(二)--拉姆达表达式

委托的另一种用法---------匿名方法: public delegate void MyDel(string msg);----声明的委托 class Program { static void Main(string[] args) { MyDel mdl = delegate(string str) { Console.WriteLine(str); }; mdl("床前明月光"); Console.ReadKey(); } }另一种简单的写法 public delegate

朗姆达表达式类似IN查询条件

if (list.Contains("全部"))            {                model.All = true;            }                                   var context = GetYWBusinessLogic().ObjectContext; var result = context.CustomerCommissionerView.Where(t => t.IsSend == 0).To

09.C#委托转换和匿名方法(五章5.1-5.4)

今天将书中看的,自己想的写出来,供大家参考,不足之处请指正.进入正题. 在C#1中开发web form常常会遇到使用事件,为每个事件创建一个事件处理方法,在将方法赋予给事件中,会使用new EventHandler(),不同的事件有各种不同的EventHandler的派生类的实例,因为我这里使用的时Console App,原理是一样的,且看 //定义一个委托 delegate void Printer(); static void Main(string[] args) { Printer p

函数细说及匿名函数

我们知道,函数是对象.每个函数 都是Function类型的实例,和其他引用类型一样具有方法和属性.由于函数是对象,因此函数名实际上是一个指向函数对象的指针. 函数有三种定义方式:函数声明,函数表达式,使用Function构造函数. 函数声明: 函数表达式: 在函数表达式中,使用变量sum即可引用函数,注意函数结尾有一个分号,就像声明其他变量一样. 构造函数(不推荐使用): 由于函数名仅仅是指向函数的指针,所以一个函数可以有很多的名字.注意使用不带圆括号的函数名是访问函数指针,而非调用函数. 在这

python学习笔记4--装饰器、生成器、迭代器、匿名函数、内置方法、数据序列话

一.装饰器 1.意义:当需要给程序中某些函数新增某项功能时,为了避免直接修改函数源代码和函数调用方式,所以引入装饰器. 2.定义:装饰器用于装饰其他函数,就是为其他函数提供附加功能. 3.原则: 1)不修改被装饰的函数的源代码 2)不修改被装饰的函数的调用方式 4.装饰器储备知识: 1)函数即变量 2)高阶函数 a.把函数当做参数传递给另一个函数(在不修改被修饰函数源代码的情况下为该函数添加功能) b.返回值中包含函数名(在不修改被修饰的函数的调用方式的情况下为该函数添加功能) 3)嵌套函数:在

对匿名函数的深入理解(彻底版)

从简单的字面理解就是一个没有名字的函数,但是如果说它只是这样简单,那我也就没有必要来说这些. 对匿名函数的理解1: function(){ console.log(1); } // 报错 不能直接使用. 对匿名函数的理解2: var a = function(){ console.log(1); } a(); //1 匿名函数可以依附于一个变量,并且这个变量名就是这个匿名函数的名字. var a = function(){ console.log(1); } console.log(typeof

python——内置函数、匿名函数

一.内置函数 内置函数操作 1 # # 1.locals()和globals() # def func(): # x=1 # y=2 # print(locals()) # print(globals()) # func() # 2.eval,exec,和compile # print(123) # "print(456)"#字符串 # eval("print(456)")#吧字符串转换成python代码去执行(有返回值) # exec("print(78

7.匿名函数

python---------匿名函数 一.匿名函数:也叫lambda表达式 1.匿名函数的核心:一些简单的需要用函数去解决的问题,匿名函数的函数体只有一行 2.参数可以有多个,用逗号隔开 3.返回值和正常的函数一样可以是任意的数据类型 二.匿名函数练习 1 请把下面的函数转换成匿名函数 2 def add(x,y) 3 return x+y 4 add() 5 结果: 6 sum1=lambda x,y:x+y 7 print(sum1(5,8)) 1 dic = {'k1':50,'k2':