迭代器匿名方法和_第1页
迭代器匿名方法和_第2页
迭代器匿名方法和_第3页
迭代器匿名方法和_第4页
迭代器匿名方法和_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第17章迭代器、匿名方法和扩展方法迭代器、匿名方法和扩展方法出现使得代码更清楚,书写更简便。迭代器是一个语句块,它能够产生一系列有序值,从而使得foreach语句能够访问该序列。匿名方法是一个特殊方法,它能够省略方法名称。扩展方法能够向现有类型“添加”新方法,它是一个静态方法,经过扩展类型实例来调用扩展方法。本章将给大家详细讲解C#语言中迭代器、匿名方法和扩展方法。迭代器匿名方法和第1页17.1使用迭代器迭代器(iterator)是一个产生有序值序列语句块,其作用是使遍历过程变得愈加轻易。它返回一组对象组员,可用作方法、运算符或存放器。比如,假定某个数组有5个组员,则该数组迭代器将返回这5个元素,每次返回一个元素。经过创建迭代器,能够在foreach循环中使用类对象。迭代器匿名方法和第2页迭代器中使用关键字是yield,这个关键字只在迭代器中才有特定含义。迭代器包含两个特有语句是yieldreturn语句和yieldbreak语句。yieldreturn语句能够产生迭代下一个值,而yieldbreak语句则指示迭代完成。当迭代器执行到yieldreturn语句时,会保留当前位置。假如该迭代器再次被调用,将从保留位置开始执行。注意:迭代器返回类型必须为(可枚举接口)IEnumerable、(枚举器接口)IEnumerator、IEnumerable<T>或Ienumeraor<T>。迭代器分为非泛型迭代器和泛型迭代器,下面我们来学习这两种迭代器。迭代器匿名方法和第3页17.1.1创建非泛型迭代器创建一个非泛型迭代器最惯用方法是实现IEnumerable接口GetEnumerator()方法。IEnumerable接口表示公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。IEnumerable接口只包含GetEnumerator()方法,它返回一个循环访问集合枚举数。【示例17-1】下面在Program类中创建一个非泛型迭代器,Program类必须满足以下两个条件。实现IEnumerable接口。实现IEnumerable接口GetEnumerator()方法。迭代器匿名方法和第4页Program类实现了IEnumerable接口GetEnumerator()方法,并在for语句中使用yieldreturn语句创建迭代器每一个元素。注意:正是因为Program类实现了IEnumerable接口GetEnumerator()方法,从而使得Program为可枚举类型,所以,能够使用foreach语句遍历Program类型实例。迭代器匿名方法和第5页17.1.2创建泛型迭代器创建一个泛型迭代器,需要实现IEnumerable和IEnumerable<T>接口GetEnumerator()方法。【示例17-2】下面在Program2<T>泛型类中创建一个泛型迭代器,Program2<T>类必须满足以下3个条件。实现IEnumerable<T>接口。实现IEnumerable<T>接口GetEnumerator()方法。实现IEnumerable接口GetEnumerator()方法。迭代器匿名方法和第6页Program2<T>类包含一个字段:stack。它类型为Stack(堆栈),并在该类结构函数中初始化了stack字段。Program2<T>类还包含可两个方法:Push(Titem)和Pop()。Push(Titem)方法将item元素压入到stack堆栈中,Pop()方法弹出stack堆栈顶部元素。Program2<T>类实现了IEnumerable和IEnumerable<T>接口GetEnumerator()方法,详细说明以下:publicIEnumerator<T>GetEnumerator()实现了IEnumerable<T>接口GetEnumerator()方法,它在while语句中使用yieldreturn语句产生迭代器元素。这些元素为stack堆栈中元素。IEnumeratorIEnumerable.GetEnumerator()方法实现了IEnumerable接口Get-Enumerator()方法,它调用上述方法实现。注意:和Program类一样,Program2<T>类也是可枚举类型。所以,能够使用foreach语句遍历Program2<T>类型实例。迭代器匿名方法和第7页17.1.3使用IEnumerator和IEnumerator<T>接口为了创建类对象能够在foreach循环中使用,必须实现IEnumerable和IEnumerator接口泛型或非泛型形式。这些接口都非常简单,所以很轻易实现。本节我们来学习IEnumerator和IEnumerator<T>接口。IEnumerator表示枚举器非泛型接口,支持对非泛型集合简单迭代。IEnumerator<T>表示枚举器泛型接口,支持泛型集合简单迭代。迭代器匿名方法和第8页1.IEnumerator接口foreach语句使用IEnumerator接口方法和属性,迭代集合中全部元素。IEnumerator是全部非泛型枚举数基接口,它包含2个方法和1个属性,详细说明以下所表示。MoveNext()方法:将枚举数推进到集合下一个元素,即将当前指定元素指针指向集合中下一个元素。Reset()方法:重置枚举数,即把枚举数设置位于集合中第一个元素之前。所以,该集合中下一个被访问元素为集合第一个元素。Current属性:获取集合中当前元素。注意:迭代器被创建之后,枚举数定位在集合中第一个元素前。此时,Current属性值为null。在调用Reset()方法后,枚举数位于在集合第一个元素之前,首次调用MoveNext()方法会将枚举数移到集合第一个元素。假如调用MoveNext()方法使得当前指针超出了集合末尾,则将指针设置为该集合最终一个元素后面,并返回false。迭代器匿名方法和第9页【示例17-3】下面首先创建Program类实例p,并获取p实例迭代器,保留为ie。然后在while语句中使用MoveNext()方法和Current属性依次显示ie实例迭代器中每一个元素值。Programp

=newProgram();

//创建Program类实例IEnumerator

ie

=p.GetEnumerator();

//获取p实例迭代器while(ie.MoveNext())

//移动到下一个元素,直到迭代器末尾{

Console.WriteLine(ie.Current);

//显示迭代器当前元素值}分析:在ie迭代器第一次调用MoveNext()方法之前,它Current属性值为null。迭代器匿名方法和第10页2.IEnumerator<T>接口IEnumerator<T>接口支持泛型集合简单迭代,它包含3个方法和1个属性,详细说明以下所表示。MoveNext()方法:将枚举数推进到集合下一个元素,即将当前指定元素指针指向集合中下一个元素。Reset()方法:重置枚举数,即把枚举数设置位于集合中第一个元素之前。所以,该集合中下一个被访问元素为集合第一个元素。Dispose()方法:释放实例所占有资源。Current属性:获取集合中当前元素。注意:IEnumerator<T>接口中MoveNext()方法、Reset()方法、Current属性和IEnumerator接口相对应方法和属性意义相同。所以,在此不做详细介绍。迭代器匿名方法和第11页17.2使用

匿名方法匿名方法(anonymousmethod)是一个隐藏了名称方法。它是创建与特定委托实例相关联命名代码块一个方式。能够经过在代码块后面添加delegate关键字来创建匿名方法。本节我们来学习匿名方法。迭代器匿名方法和第12页17.2.1创建匿名方法创建匿名方法方式和普通方法不一样。匿名方法由delegate关键字、参数列表(可选)和包含在“{”和“}”分隔符中语句列表组成。从匿名方法组成元素能够看到,匿名方法已经省略了该方法名称。【示例17-4】下面向btnAdd(Button类实例)Click事件注册了一个匿名方法。该匿名方法省略参数列表,并显示“这是一个匿名方法。”。btnAdd.Click+=delegate

//btnAdd是Button类实例,它包含Click事件{

Console.WriteLine("这是一个匿名方法。");}迭代器匿名方法和第13页【示例17-5】下面代码等效于示例17-4中代码。btnAdd.Click+=new

EventHandler(AddClick);void

AddClick(objectsender,EventArgse){

Console.WriteLine("这是一个匿名方法。");}分析:上述程序代码创建了AddClick(objectsender,EventArgse)方法,并经过委托将该方法注册到btnAdd(Button类实例)Click事件。示例17-4和示例17-5实现了一样功效,不过示例17-5为方法提供了一个显式命名。注意:在示例17-4中,发生了从匿名方法到EventHandler委托类型(Button类Click事件类型)隐式转换。而且,只有当委托参数列表和返回类型都必须与匿名方法兼容时,才能进行从匿名方法到委托类型隐式转换。迭代器匿名方法和第14页【示例17-6】下面向btnAdd(Button类实例)Click事件注册了一个匿名方法。该匿名方法包含了参数列表(包含2个参数:sender和e),并显示“这是一个匿名方法。”。btnAdd.Click+=delegate(objectsender,EventArgse)

//btnAdd是Button类实例,它包含Click事件{

Console.WriteLine("这是一个匿名方法。");}迭代器匿名方法和第15页17.2.2将匿名方法作为参数传递因为匿名方法允许与委托关联代码以“内联”方式,所以能够将匿名方法作为方法参数来传递。【示例17-7】下面代码实现以下3个功效。创建委托Weituo。该委托返回类型为int,并包含1个参数:i,类型为int。创建int[]

Array(int[]array,Weituo

w)方法。该方法包含两个参数:array和w,array是一个元素类型为int数组,w类型为Weituo。该方法调用w委托方法对array数组上每一个元素进行计算。最终,将计算结果作为该方法返回值。创建array数组,它包含5个元素(1、2、3、4和5)。最终调用Array

(int[]array,Weituo

w)方法对array数组进行计算,计算结果保留为result数组。注意:在调用Array(int[]array,Weituo

w)方法时,将“delegate(inti){returni*

i;}”匿名方法作为参数来传递。该匿名方法用于计算i参数平方。迭代器匿名方法和第16页delegateint

Weituo(inti);

//创建Weituo委托int[]

Array(int[]array,Weituow)//创建int[]

Array(int[]array,Weituo

w)方法{

int[]result=newint[][array.Length];

for(inti=0;i<result.Length;i++)

{

result[i]=w(array[i]);

//调用w委托方法对array数组上每一个元素进行计算

}

returnresult;}int[]array={1,2,3,4,5};//调用Array(int[]array,Weituow)方法对array数组进行计算int[]result=Array(array,delegate(inti){returni*

i;});迭代器匿名方法和第17页17.3使用扩展方法扩展方法能够使得开发人员能够向现有类型“添加”新方法,使用时不需要去修改或编译类型本身代码。扩展方法是一个静态方法,能够经过扩展类型实例来调用扩展方法。迭代器匿名方法和第18页17.3.1申明扩展方法扩展方法在使用之前也要申明。申明扩展方法时,需要使用this修饰符。扩展方法第一个参数指定该方法所作用类型,并使用this修饰符作为该参数前缀。注意:扩展方法必须申明为静态方法,且必须申明在静态类中。迭代器匿名方法和第19页【示例17-8】下面向Program静态类添加一个扩展方法:ToInt32(thisstringstr)。ToInt32

(thisstring

str)方法也为静态方法,它能够被string类型(由this修饰符指定)实例调用,并将字符串转换为对应整数。01

usingSystem;02

namespace示例chapter17//指定命名空间03

{04

publicstaticclassProgram//申明扩展方法静态类05

{06

publicstaticintToInt32(thisstringstr)07

//申明扩展方法,并指定扩展类型为string08

{09

returnInt32.Parse(str);10

}11

}12

}分析:ToInt32(thisstringstr)扩展方法申明在“示例chapter17”命名空间Program静态类中。迭代器匿名方法和第20页【示例17-9】下面向Programs静态类添加一个扩展方法:ToInt32WithD

(thisstringstr,intd)。ToInt32WithD(thisstringstr,intd)方法也为静态方法,它包含两个参数:str和d。str参数类型为string,被this修饰符修饰,所以,该扩展方法能够被string类型实例调用。d参数类型为int。ToInt32WithD(thisstringstr,intd)方法首先将str转换为一个整数,然后除以d参数,并返回计算结果。01

usingSystem;02

namespace示例chapter17//指定命名空间03

{04

publicstaticclassProgram//申明扩展方法静态类05

{06

publicstaticintToInt32WithD(thisstringstr,intd)07

//申明扩展方法,并指定扩展类型为string08

{09

return(int)((double)Int32.Parse(str)/d);10

}11

}12

}分析:ToInt32WithD

(thisstringstr,intd)扩展方法也被申明在“示例chapter17”命名空间Program静态类中。迭代器匿名方法和第21页普通情况下,不提议使用扩展方法。在申明扩展方法时,需要注意以下两点。假如扩展方法与其相关类型中定义方法含有相同署名,则扩展方法永远不会被调用。扩展方法属于其所在命名空间。所以,假如使用using指令引入某一个命名空间,那么该命名空间中全部扩展方法都将被导入。迭代器匿名方法和第22页17.3.2导入扩展方法导入扩展方法比较简单,只要使用using指令引入扩展方法所在命名空间即可。实际上,被导入扩展方法作为该方法第一个参数类型附加方法。【示例17-10】下面使用using指令引入“示例chapter17”命名空间,同时也导入该命名空间中扩展方法,如示例17-8中申明ToInt32

(thisstringstr)方法、示例17-9中申明T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论