C# 3.0(C# Orcas——魔鬼)在C# 2.0的基础上引入了很多语言扩展,用以支持高级别的函数式风格类库的创建和使用。这些扩展使得结构性API构造具有与其他领域(如关系数据库和XML)中查询语言同等的表达能力。这些扩展包括:
具有隐式类型的局部变量,允许通过用于初始化的表达式来推断局部变量的类型。
扩展方法,使得对一个现存类型的扩展和构造具有附加方法的类型变为现实。
拉姆达(Lambda)表达式,匿名方法的一种进化,为委托类型和表达式树提供了改进的类型推断和转换。
对象初始化器,使得构造和初始化对象变得容易。
匿名类型,由对象初始化器推断和创建出来的类型。
具有隐式类型的数组,从数组初始化器推断出元素类型并进行创建和初始化的数组。
查询表达式,提供了集成的查询语法,与关系、分级查询语言如SQL和XQuery类似。
表达式树,允许将拉姆达表达式表现为数据(表达式树),而不是代码(委托)。
1 具有隐式类型的局部变量
在一个具有隐式类型的局部变量声明(implicitly typed local variable declaration)中,被声明的局部变量的类型是通过初始化该变量的表达式推断出来的。当使用局部变量声指示符符var来代替类型,并且当前作用域内没有名为var的类型时,这个声明便成为一个具有隐式类型的局部变量声明。例如:
var i = 5; var s = "Hello"; var d = 1.0; var numbers = new int[] {1, 2, 3}; var orders = new Dictionary<int, Order>();
上面这些具有隐式类型的局部变量声明和下面这些具有显式类型的声明完全一致:
int i = 5; string s = "Hello"; double d = 1.0; int[] numbers = new int[] {1, 2, 3}; Dictionary<int, Order> orders = new Dictionary<int, Order>();
一个具有隐式类型的局部变量声明中的局部变量声明器(Declarator)必须遵循下列约束:
该声明器必须包含初始化器。
初始化器必须是一个表达式。该初始化器不能是它自己的对象或集合初始化器(第4部分),但可以是一个包含了对象或集合初始化器的new表达式。
初始化器表达式在编译期的类型必须不能为空类型。
如果局部变量的声明包含多个声明器,所有的初始化器在编译期都必须具有相同的类型。 下面是不正确的具有隐式类型的局部变量声明示例:
var x; // 错误,没有用来推断类型的初始化器 var y = {1, 2, 3}; // 错误,不允许使用集合初始化器 var z = null; // 错误,不允许出现空类型
出于向下兼容的原因,当一个局部变量声明指示符以var作为类型,但当前作用域中有一个名为var的类型时,这个声明使用的是该类型;然而,(编译器)会针对这种模糊的语义给出一个警告。不过由于var违反了类型名字首字母必须大写这条约定,这种情况应该不大会出现。
for语句的for-initializer和using语句的resource-acquisition可以是一个具有隐式类型的局部变量声明。同样,foreach语句中的迭代变量也可以被声明为具有隐式类型的局部变量,在这种情况下,迭代变量的类型通过待遍历的集合的元素类型来推断。
int[] numbers = {1, 3, 5, 7, 9}; foreach(var n in numbers) Console.WriteLine(n);
在上面的例子中n的类型被推断为int——numbers的元素类型。
2 扩展方法
扩展方法(Extension Method)是一种静态方法,可以通过实例方法的语法进行调用。从最终效果上看,扩展方法使得扩展一个现有类型和构造一个具有附加方法的类型变成了现实。
注意
扩展方法很难发觉,并且比起实例方法在功能性上有很大限制。出于这些原因,我们建议保守地使用扩展方法,仅在实例方法不大可行或根本不可行的时候才使用。 扩展成员的其他类型,如属性、事件和运算符都在考虑之中,但目前并未支持。
2.1 声明扩展方法
扩展方法通过在方法的第一个参数上指定关键字this作为一个修饰符来声明。扩展方法只能声明在静态类中。下面的示例是一个声明了两个扩展方法的静态类:
namespace Acme.Utilities { public static class Extensions { public static int ToInt32(this string s) {
复制本页网址和标题,发送给你QQ/Msn的好友一起分享
上一篇:用axis开发webservice实践
下一篇:.net 中委托与事件的理解