1、新语法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、新语法
在学习 MVC之前,有必要先了解一下C#3.0所带来的新的语法特性,这一点尤为重要,因为在MVC项目中我们利用C#3.0的新特性将会大大的提高我们的开发效率,同时,在MVC项目中你将到处可以看到C#3.0新特性的身影。其本质都是“语法糖”,由编译器在编译时转成原始语法。
目录
∙自动属性
∙隐式类型 var
∙参数默认值和命名参数
∙对象初始化器与集合初始化器
∙匿名类& 匿名方法
∙扩展方法
∙系统内置委托:Func / Action
∙Lambda表达式
∙标准查询运算符(SQO)
∙LINQ
自动属性
这个概念很简单,其简化了我们在.NET的时候手写一堆私有成员+属性的编程方式,我们只需要使用如下方式声明一个属性,编译器会自动生成所需的成员变量。
回顾传统属性概念,属性的目的:封装字段,控制 1.读写权限及 2.字段的访问规则(如:年龄范围)。但平时,主要是用来封装读写权限。
基本用法:
在C#3.0之前,我们是这样来实现属性的:
思考:
用自动属性的话程序员写的代码少了,机器做的事情就多了,那我们到底要不要使用它?如果是针对读写权限的封装,就推荐使用,因为它是在编译的时候产生了负担,并不是在运行的时候。(不会影响客户运行程序时的效率!)但是编译生成的代码也有一个显而易见的缺点,语法太完整,编译后的程序集会比较大。
隐式推断类型
这个名称可能对你很陌生,但是var这个关键字应该都用过,在C#中使用var声明一个对象时,编译器会自动根据其赋值语句推断这个局部变量的类型。赋值以后,这个变量的类型也就确定而不可以再进行更改。另外var关键字也用于匿名类的声明。
应用场合:var主要用途是表示一个LINQ查询的结果。这个结果可能是ObjectQuery<>或IQueryable<>类型的对象,也可能是一个简单的实体类型的对象。这时使用var声明这个对象可以节省很多代码书写上的时间。
var隐式类型的限制
1.被声明的变量是一个局部变量,而不是静态或实例字段;
2.变量必须在声明的同时被初始化;编译器要根据初始化值推断类型
3.初始化不能是一个匿名函数;
4.初始化表达式不能是 null;
5.语句中只声明一次变量,声明后不能更改类型;
6.赋值的数据类型必须是可以在编译时确定的类型;
参数默认值和命名参数
运行结果:
如果要name使用默认值,age给值怎么办?
对象集合初始化器
在.NET2.0中构造一个对象的方法一是提供一个重载的构造函数,二是用默认的构造函数生成一个对象,然后对其属性进行赋值。在.NET3.5/C#3.0中我们有一种更好的方式来进行对象的初始化。那就是使用对象初始化器。这个特性也是匿名类的一个基础,所以放在匿名类之前介绍。需要注意的是,它最终还是离不开构造函数,它其实是使用默认的构造函数生成了一个对象。
对象初始化:
集合初始化:
创建并初始化数组:
匿名类
有了前文初始化器的介绍,匿名类就很简单了。我们可以使用new { object
initializer }或new[]{ object, …}来初始化一个匿名类或不确定类型的数
组。匿名类的对象需要使用var关键字声明。示例代码:
在编译后会生成一个【泛型类】,包含:
a. 获取所有初始值的构造函数,顺序与属性顺序一样;
b.公有的只读属性,属性不能为null/匿名函数/指针;
c.属性的私有只读字段;
d.重写的Equals,GetHashCode,ToString()方法
用处:
a.避免过度的数据累积
b.为一种情况特别进行的数据封装
c.避免进行单调重复的编码
应用场合:当直接使用select new { object initializer }这样的语法就是
将一个LINQ查询的结果返回到一个匿名类中。
注意:
1. 当出现“相同”的匿名类的时候,编译器只会创建一个匿名类
2. 编译器如何区分匿名类是否相同?
根据:属性名,属性值(因为这些属性是根据值来确定类型的),属性个数,属性的顺序。
3、匿名类的属性是只读的,可放心传递,可用在线程间共享数据
匿名方法
函数式编程的最大特点之一:把方法作为参数和返回值。 DGShowMsg
->MulticastDelegate(intPtr[]) -> Delegate(object,intPtr)
匿名方法:编译后会生成委托对象,生成方法,然后把方法装入委托对象,最后赋值给声明的委托变量。
匿名方法可以省略参数:编译的时候会自动为这个方法按照委托签名的参数添加参数
扩展方法
扩展方法的本质:编译时,直接将 str.WriteSelf(2015) 替换成StringUtil.WriteSelf(str,2015);想为一个类型添加一些成员 , 怎么办?
扩展方法:
测试:
本质就是静态方法
编译器认为一个表达式是要使用一个实例方法,但没有找到,就会检查导入
的命名空间和当前命名空间里所有的扩展方法,并匹配到适合的方法.
注意:
1.实例方法优先于扩展方法(允许存在同名实例方法和扩展方法)
2.可以在空引用上调用扩展方法!
3.可以被继承
4.并不是任何方法都能作为扩展方法使用,必须有特征:
它必须放在一个非嵌套、非泛型的静态类中(的静态方法);
它至少有一个参数;
第一个参数必须附加 this 关键字;
第一个参数不能有任何其他修饰符(out/ref)
第一个参数不能是指针类型
看看这两个接口的方法:IEnumerable
系统内置委托:Func / Action
委托使用可变性 :
协变指的是委托方法的返回值类型直接或间接继承自委托签名的返回值类型,逆变则是参数类型继承自委托方法的参数类型
System.Func 代表有返回类型的委托
注:输入泛型参数-in 最多16个,输出泛型参数 -out 只有一个。System.Action 代表无返回类型的委托
注:参数最多16个
System.Predicate
为什么要定义这么多简单的委托? 方便!