天天看点

C#3.0 新特性速览(2)

  上篇文章中介绍了C# 3.0中比较简单的四个特性,分别是隐式类型化本地变量、匿名类型、隐式类型化数组,以及对象构造者,下面我将对C# 3.0中的较复杂,同时也是非常强大的几个特性进行介绍,供大家快速浏览。

第五个特性:集合构造者

  我们可以在声明数组的同时,为其指定初始值,方法是直接在数组声明的后面跟上初始值列表。这样就使数组的初始化工作变得简单,而对于我们自己创建的集合类型,就无法享受到与普通数组一样的待遇了,我们无法在创建自定义集合对象的同时,使用数组的初始化语法为其指定初始值。

  C# 3.0中加入的集合构造者特性,可使我们享受到与普通数组一样的待遇,从而在创建集合对象的同时为其指定初始值。为了做到这一点,我们需要让我们的集合实现ICollection<T>接口,在这个接口中,完成初始化操作的关键在于Add函数,当我使用初始化语法为集合指定初始值时,C#编译器将自动调用ICollection<T>中的Add函数将初始列表中的所有元素加入到集合中,以完成集合的初始化操作。使用示例如下:

1:      class  : AppRunner.      
2:      {      
3:          class  : <string>      
4:          {      
5:              public void Add(string item)      
6:              {      
7:                  .WriteLine(item);      
8:              }      
9:         
10:              // Other ICollection<T> Members      
11:          }      
12:         
13:          public override void Run()      
14:          {      
15:               strings = new () { , ,  };      
16:          }      
17:      }      

  在这个示例中,编译器会自动为strings对象调用Add方法,以将初始值列表中的所有元素加入到集合中,这里我们只是简单将初始值列表中的元素输出到控制台。

第六个特性:Lambda表达式

  C# 2.0中加入的匿名代理,简化了我们编写事件处理函数的工作,使我们不再需要单独声明一个函数来与事件绑定,只需要使用delegate关键字在线编写事件处理代码。

  而C# 3.0则更进一步,通过Lambda表达式,我们可以一种更为简洁方式编写事件处理代码,新的Lambda事件处理代码看上去就像一个计算表达式,它使用"=>"符号来连接事件参数和事件处理代码。我可以这样写:SomeEvent += 事件参数 => 事件处理代码;下面是完整的示例:

1:      delegate T <T>(T a, T b);      
2:         
3:      class  : AppRunner.      
4:      {      
5:          public static event  MyEvent;      
6:         
7:          public override void Run()      
8:          {      
9:              MyEvent += delegate(object s,  e)      
10:              {      
11:                  .WriteLine(s);      
12:              };      
13:         
14:              MyEvent += (s, e) => { .WriteLine(s); };      
16:              MyEvent(this, null);      
17:         
18:              <string> add = (a, b) => a + b;      
19:         
20:              .WriteLine(add(, ));      
21:          }      
22:      }      

  在上面的例子中,分别使用了匿名代理和Lambda表达式来实现同样的功能,可以明显看出Lambda表达式的实现更为简洁。我们在使用Lambda表达式编写事件处理代码时,无需指明事件参数的类型,且返回值就是最后一条语句的执行结果。

第七个特性:扩展方法

  当我们需要对已有类的功能进行扩展时,我们通常会想到继承,继承已有类,然后为其加入新的行为。而C# 3.0中加入的扩展方法特性,则提供了另一种实现功能扩展的方式,我们可以在不使用继承的前提下实现对已有类本身的扩展,这种方法并不会产生新的类型,而是采用向已有类中加入新方法的方式来完成功能扩展。

  在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。而且扩展方法采用一种全新的声明方式:public static 返回类型 扩展方法名(this 要扩展的类型 sourceObj [,扩展方法参数列表]),与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。下面是使用示例:

2:      {      
3:          public static int ToInt32(this string source)      
4:          {      
5:              return .Parse(source);      
6:          }      
7:         
8:          public static T[] Slice<T>(this T[] source, int index, int count)      
9:          {      
10:              if (index < 0 || count < 0 || index + count > source.Length)      
11:              {      
12:                  throw new ArgumentException();      
13:              }      
14:         
15:              T[] result = new T[count];      
16:              .Copy(source, index, result, 0, count);          
17:              return result;      
18:          }      
19:      }      
20:         
21:      class  : AppRunner.      
22:      {      
23:          public override void Run()      
24:          {      
25:              string number = ;      
26:              .WriteLine(number.ToInt32());      
27:         
28:              int[] intArray = new int[] { 1, 2, 3 };      
29:         
30:              intArray = intArray.Slice(1, 2);      
31:         
32:              foreach (var i in intArray)      
33:                  .WriteLine(i);      
34:          }      
35:      }      

  在上面的示例中,静态的Extensions类中有两个扩展方法,第一个方法是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字符向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。

  第二个扩展方法是一个范型方法,它是对所有数组类型的扩展,该方法完成数组的切片操作。

  C# 3.0中的Linq表达式,就是大量运用扩展方法来实现数据查询的。

第八个特性:Linq查询表达式

  C# 3.0中加入的最为复杂的特性就是Linq查询表达式了,这使我们可直接采用类似于SQL的语法对集合进行查询,这就使我们可以享受到关系数据查询的强大功能。

  Linq查询表达式是建立在多种C# 3.0的新特性之上的,这也是我为什么最后才介绍Linq的原因。下面看一个例子:

1:      class  : AppRunner.      
2:      {      
3:          public override void Run()      
4:          {      
5:              // 定义匿名数组persons, 并为其赋初值      
6:               persons = new[] {      
7:                  new { Name=, Sex=false, Age=22 },      
8:                  new { Name=, Sex=true, Age=30 },      
9:                  new { Name=, Sex=false, Age=24 },      
10:                  new { Name=, Sex=false, Age=25 },      
11:                  new { Name=, Sex=true, Age=20 }      
12:              };      
13:         
14:         
15:              /*      
16:                  执行简单Linq查询      
17:         
18:                  检索所有年龄在24岁以内的人      
19:                  查询结果放在results变量中      
20:        
21:                  results变量的类型与数组persons相同                      
22:              */      
23:               results =  p in persons      
24:                            where p.Age <= 24      
25:                             p;      
26:         
27:              foreach ( person in results)      
28:              {      
29:                  .WriteLine(person.Name);      
30:              }      
31:         
32:              .WriteLine();      
33:         
34:         
35:              // 定义匿名数组customers, 并为其赋初值      
36:              // 该数组是匿名类型的      
37:               customers = new[] {      
38:                  new {      
39:                      Name=, City=, Orders=new[] {      
40:                          new {      
41:                              OrderNo=0,      
42:                              OrderName=,      
43:                              OrderDate=new (2007,9, 5)      
44:                          },      
45:                          new {      
46:                              OrderNo=1,      
47:                              OrderName=,      
48:                              OrderDate=new (2007,9,15)      
49:                          },      
50:                          new {      
51:                              OrderNo=2,      
52:                              OrderName=,      
53:                              OrderDate=new (2007,09,18)      
54:                          },      
55:                          new {      
56:                              OrderNo=3,      
57:                              OrderName=,      
58:                              OrderDate=new (2002, 9, 20)      
59:                          }      
60:                      }      
61:                  },      
62:                  new {      
63:                      Name=, City=, Orders=new[] {      
64:                          new {      
65:                              OrderNo=0,      
66:                              OrderName=,      
67:                              OrderDate=new (2007, 9, 15)      
68:                          }      
69:                      }      
70:                  },      
71:                  new {      
72:                      Name=, City=, Orders=new[] {      
73:                          new { OrderNo=0,      
74:                              OrderName=,      
75:                              OrderDate=new (2007, 9, 20)      
76:                          }      
77:                      }      
78:                  }      
79:              };      
80:         
81:         
82:              /*      
83:                  执行多重Linq查询      
84:         
85:                  检索所在城市为中国, 且订单日期为2007年以后的所有记录      
86:                  查询结果是一个匿名类型的数组      
87:                  其中包含客户名, 订单号, 订单日期, 订单名四个字段      
88:              */      
89:               someCustomers =  c in customers      
90:                                  where c.City == "China"      
91:                                   o in c.Orders      
92:                                  where o.OrderDate.Year >= 2007      
93:                                   new { c.Name, o.OrderNo, o.OrderDate, o.OrderName };      
94:         
95:         
96:              foreach ( customer in someCustomers)      
97:              {      
98:                  .WriteLine(      
99:                      customer.Name + ", " + customer.OrderName + ",  " +      
100:                      customer.OrderDate.ToString("D")      
101:                  );      
102:              }      
103:          }      
104:      }      

  从上面的例子中,我们可以看到Linq查询的强大特性,它允许我们进行简单查询,或者进行更为复杂的多重连接查询。且查询的结果还可以是自定义的匿名类型。

  以上是对C# 3.0中新增的八大特性的简要介绍,如果想了解更为深入的内容,可查看C# 3.0的官方规范。

相关文章:C#3.0 新特性速览(1)

转载于:https://www.cnblogs.com/JiaweiZONE/archive/2007/09/29/910645.html

c#