C#3.0特性总结.doc_第1页
C#3.0特性总结.doc_第2页
C#3.0特性总结.doc_第3页
C#3.0特性总结.doc_第4页
C#3.0特性总结.doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

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

文档简介

一.C# 3.0语言主要增强点 隐含类型局部变量 扩展方法 对象与集合初始化器 匿名类型 Lambda表达式 查询表达式( LINQ ) 表达式树二.隐含类型局部变量先来看看例句:var i = 5;var h=23.56;var s = “C Sharp;var intArr = new 1,2,3,4 ;var a = new 1, 10, 100, 1000 ;var这个关键字是不是很眼熟,javascript中经常用到(互相学习现在比较常见了),当然C#中var和javascript的var差别还是比较大。1.var只能作为局部变量使用;就是说var只能定义在一个方法里面,或者foreach,for,using等语句里面:public class VarTestprivate void test()var i = 0;2.var可以申明任何类型变量,可以根据后面的初始化语句自动推断类型;这个和object有点像,但var是强类型,根据初始化表达式来定义变量的类型;var i=0; i 是int类型var str = test; str是string类型3.var定义时,必须使用表达式初始化;也就是必须定义成 var i=0; 没有初始化编译会报错,而且初始化值不能为null,编译器无法根据null来推断出局部变量的类型;初始值除了int,string等数据类型外,还可以使用new 一个对象作为初始值(从网上大家发表的看法,var使用最多的就是配合一个匿名类型的对象来使用,以及在Linq中使用)/下面是网上某个网友写得博客,拷贝修改了一下!配合匿名类型使用:vara=newName=maotin,Age=99;Console.WriteLine(a.Name);Console.WriteLine(a.Age);在linq中应用:intnumbers=5,4,1,3,9,8,6,7,2,0;varqueryLowNums=fromnuminnumberswherenum5selectnum;foreach(varsinqueryLowNums) Console.Write(s.ToString()+); 4.var使用建议一般var不要像“var i=9;”这样使用,程序可读性不高;在匿名类型中使用比较方便;foreach中使用也不错;var只是语言层面的东西,编译器会在编译的时候通过类型推断把它换成真正的类型三.扩展方法)扩展方法定义如下:public static class Extensionspublic static void Foo(this string s) 使用:String s=“Hello,World”;s.Foo();我们以前会对一些参数、对象进行某些处理,而写一些独立方法来封装这些处理语句;这些方法为了方便重用,可能会写在一些公共类里供大家调用,例如:定义一个公共方法计算每天有多少分钟,public class PublicCenter/传入参数为天数public long GetDaysMin(int pDays) return pDays * 24 * 60; 外部使用调用:int days = 3;PublicCenter pCenter = new PublicCenter();int minutes = pCenter.GetDaysMin(days);看看用扩展方法来处理会是怎么样;定义一个静态类的静态方法计算每天有多少分钟(注意必须是静态)public staticclass PublicCenter/传入参数为天数(注意this关键字必不可少)public staticlong GetDaysMin( this int pDays) return pDays * 24 * 60; 外部使用调用:(注意静态类必须同在一个命名空间,或添加引用,这个大家应该也知道的(啰嗦)int days = 3;/当我们在所以int类型的变量后按下.,就会智能提示出这些自己写的扩展方法GetDaysMin()。int minutes = days.GetDaysMin()可以看出扩展方法的本质为将实例方法调用在编译期改变为静态类中的静态方法调用。MSDN中对扩展方法的定义是:扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。为什么使用扩展方法?第一.使用方便:定义好某个类型的扩展方法后,只要是在这个类型后面点一个“.,就可以找到所有的扩展方法;而不用像以前先要找到方法所放的那个类,然后用通过调用该类的方法来实现;(很多时候,公共类库和实际调用是不同开发人员开发的,往往需要调用的人员不知道哪个类有哪些功能可以使用,这个在公共类库比较庞大的时候很麻烦)第二.扩展方便:可以很方便的扩展底层类库,接口,第三方类库(控件,插件)等等,在上面添加我们需要的功能;而不需要我们重新修改这些底层类库,控件等(有很多时候这些东西我们根本没有办法更改,例如第三方提供的,非开源的);扩展方法几种使用情况:1.传递参数:public static class Extensions/this必须放第一个位置,后面传递参数类型没有限制public static void Foo(this string s,string pName) 使用:String s=“Hello,World”;s.Foo(maotin);2.扩展方法的优先级:注意扩展方法的优先级:现有实例方法优先级最高,其次为最近的namespace下的静态类的静态方法,最后为较远的namespace下的静态类的静态方法。情况一 : 扩展方法跟原来类的方法重名时候的处理逻辑。namespace Hongjun.Guo public class MyClass public void Print() Console.WriteLine(*); static class MyExtensionMethods internal static void Print(this MyClass s) Console.WriteLine(haha + s.ToString(); 调用范例:using Hongjun.Guo;static void Main(string args) MyClass o = new MyClass(); o.Print(); Console.ReadLine();这时候我们会看到何种结果呢?答案:看到的是 *分析:我们把上述两组代码编译后,再反编译成IL,我们就可以看到,实际上,扩展方法在IL层上是不存在的。扩展方法实际是编译器调用某个类的某个方法的时候,先去这个类找,如果有这个方法,则就调用;如果找不到,根据引用的命名空间,再去找扩展方法(静态类的静态方法)。找到,就使用,找不到当然就编译错误了。根据这个分析结果,我们就可以理解上述问题处理的结果了。情况二: 扩展方法的嵌套比如我们有如下扩展方法。namespace Hongjun.Guo static class MyExtensionMethods public static int Test01(this int i) return i * 3; public static int Test02(this int i) return i + 5; 下面是调用范例:static void Main(string args) int mm = 7; Console.WriteLine(mm.Test01().Test02(); Console.WriteLine(*); Console.WriteLine(mm.Test02().Test01(); Console.WriteLine(*); Console.WriteLine(MyExtensionMethods.Test02(MyExtensionMethods.Test01(mm); Console.ReadLine();问,调用的显示结果是何值?答案: 依次显示: 26,36,26分析:mm.Test01().Test02()这行代码编译后相当于如下代码:MyExtensionMethods.Test02(MyExtensionMethods.Test01(mm)这两行代码在编译后的IL中是完全一样的。扩展方法冲突也是要考虑的问题,如果对同一个类定义了相同的扩展函数(方法名,参数都一样),在外面调用是就会产生调用不明确的编译问题,因此定义扩展方法也需要考虑是否冲突!扩展方法提供了不错一种编程方式,在日常工作中应该会逐渐被引进,但是也有一些限制,目前体会还不是很深入,后期有新观点会不断补充!扩展方法是一种编译时技术,注意与反射等运行时技术进行区别,并慎重使用。五.匿名类型/匿名类型var p1 = new Name=张三,Age=28;var p2 = new Name=李四,Age=29;var intArr = new 1,2,3,4,5;首先我们来看一下上面这段代码,比较简单,和我们平时定义一个实例基本没什么区别,只是new后面没有跟具体定义的类型;这里我们使用new关键字调用匿名初始化器创建了一个匿名类型对象;匿名类型直接继承自System.Object;匿名类型的成员是编译器根据初始化器推断而来的一些读写属性。这里我们注意到匿名类型基本上是配合隐式类型var来使用的,而且定义的顺序也是一定要注意,上面p1和p2初始化时定义的属性名、类型和顺序一致,因此编译器认为他们是同一个类型,可以使用p1=p2这样的赋值语句;特别是顺序需要注意,如果初始化时名称类型一致而顺序不一致,则p1和p2就是两个类型,如果使用p1=p2则编译时会抛出错误:无法将类型“AnonymousType#1”隐式转换为“AnonymousType#2”。定义匿名类型时还需要注意,不能用null赋初始值。匿名类型解析:匿名类型的基础是对象初始化器,匿名类型从对象初始化器(object initializer)自动推断和生成的元组类型。下面我们来看看匿名类型到底怎么生成的和我们原来的定义方式有什么区别:var p1 = new Name=张三,Age=28;我们给p1赋了一个匿名类型,在编译时,编译器使用对象初始化器推断的属性来创建见一个新的匿名类型,该类型拥有Name和Age的属性,在运行时,会创建新类型的一个实例同时Name和Age属性将会被设置为对象初始化器中指定的值“张三”、28;和上面几节里描述的一样这里大家一定会想到,肯定又是在编译器里封装了一些处理;确实是这样,下面这段代码描述编译器针对匿名类型语句具体做了哪些工作:class _Anonymous1private string name;private int age;public string Namegetreturn name; setname=value;public int Agegetretu

温馨提示

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

评论

0/150

提交评论