C# 2.0&3.0新特性总结

c#2.0新特性

范型


我们知道通用的数据结构可以采用object存储任何数据类型。使用object问题是:

  • 显示的强制转带来的代码复杂性
  • 换装箱拆箱的性能损失(为什么有性能损失?因为涉及动态内存分配和运行时类型检查)。还有一些运行时才会出现的类型转换异常也是我们难以在代码编写的时候能够检查到的,防不胜防。

范型应时而生,它的思路是什么呢?它接受带有类型参数并存储这个类型而不转换它,类型参数在类名字后的<T>中指定。T相当于一个占位符,直到使用的时候才指定一个实际的类型。确切的说当应用程序首次创建一个构造范型类型的实例时,.net公共语言运行时的实时编译器JIT将在进程中把范型IL和元数据转化为本地代码并把类型参数转化为实际的类型。对于这个泛型类型的后续引用将会使用相同的本机代码。这也就是传说中的范型类型实例化。

看一段代码:

范型的一个有趣话题:约束

问题溯源:由于T代表的可能是任何类型,所以我们使用T的方法仅限于Equals GetHasCode ToString,那么我们要使用某些特定数据类型的方法呢?比如实现了IComparable接口的数据类型的CompareTo方法?

C# 2.0&3.0新特性总结

一种方法是强制转换到IComparable接口。这种方法的缺点是:1.进行运行时动态类型检查增加了性能上的开销,2.自然地如果key没有实现IComparable接口的异常报告推迟到了运行时


另一种方法就是约束列表,关键词是
where,后面跟的是类或者接口的列表,还有一个可选、特殊的new()约束;其实就是说这个类型必须要有一个公开无参构造函数,这就允许泛型类使用这种构造函数来创建实例。约束是一把双刃剑,一方面它提供了编译时类型检查,增强了性能,但是它也限制了范型类型的能力。
C# 2.0&3.0新特性总结

范型方法
范型方法在方法名字后面使用
<>指定一个或者多个类型参数,类型参数可以出现在参数列表,返回类型和方法体内。编译器会使用一种类型推断的机制通过其他参数类推断正确的类型参数。

给出一些范型的例子:

C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结Code
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1C# 2.0&3.0新特性总结publicclassTest<T>
2C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
3C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结publicTitemC# 2.0&3.0新特性总结{get;set;}
4C# 2.0&3.0新特性总结
5C# 2.0&3.0新特性总结publicvoidDisplay()
6C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
7C# 2.0&3.0新特性总结Console.WriteLine(item.ToString());
8C# 2.0&3.0新特性总结}

9C# 2.0&3.0新特性总结
10C# 2.0&3.0新特性总结}

11C# 2.0&3.0新特性总结
12C# 2.0&3.0新特性总结publicclassMap<K,V>
13C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
14C# 2.0&3.0新特性总结Dictionary<K,V>d=newDictionary<K,V>();
15C# 2.0&3.0新特性总结publicvoidAdd(Kkey,Vvalue)
16C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
17C# 2.0&3.0新特性总结
18C# 2.0&3.0新特性总结d.Add(key,value);
19C# 2.0&3.0新特性总结}

20C# 2.0&3.0新特性总结publicvoidDisplay()
21C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
22C# 2.0&3.0新特性总结foreach(varitemind.Keys)
23C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
24C# 2.0&3.0新特性总结Console.WriteLine("Key:"+item+"Value:"+d[item]);
25C# 2.0&3.0新特性总结}

26C# 2.0&3.0新特性总结}

27C# 2.0&3.0新特性总结}

28C# 2.0&3.0新特性总结
29C# 2.0&3.0新特性总结publicclassComparableTest<T>whereT:IComparable
30C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
31C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结publicTitemC# 2.0&3.0新特性总结{get;set;}
32C# 2.0&3.0新特性总结
33C# 2.0&3.0新特性总结publicvoidDisplay()
34C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
35C# 2.0&3.0新特性总结if(item.CompareTo(10)>0)
36C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
37C# 2.0&3.0新特性总结Console.WriteLine(item.ToString()+">"+"10");
38C# 2.0&3.0新特性总结}

39C# 2.0&3.0新特性总结else
40C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
41C# 2.0&3.0新特性总结Console.WriteLine(item.ToString()+"<"+"10");
42C# 2.0&3.0新特性总结}

43C# 2.0&3.0新特性总结}

44C# 2.0&3.0新特性总结
45C# 2.0&3.0新特性总结}

46C# 2.0&3.0新特性总结
47C# 2.0&3.0新特性总结publicclassMapWithConstraint<K,V>whereV:new()
48C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
49C# 2.0&3.0新特性总结Dictionary<K,V>d=newDictionary<K,V>();
50C# 2.0&3.0新特性总结publicvoidAdd(Kkey,Vvalue)
51C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
52C# 2.0&3.0新特性总结
53C# 2.0&3.0新特性总结d.Add(key,value);
54C# 2.0&3.0新特性总结}

55C# 2.0&3.0新特性总结publicvoidDisplay()
56C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
57C# 2.0&3.0新特性总结foreach(varitemind.Keys)
58C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
59C# 2.0&3.0新特性总结Console.WriteLine("Key:"+item+"Value:"+d[item]);
60C# 2.0&3.0新特性总结}

61C# 2.0&3.0新特性总结}

62C# 2.0&3.0新特性总结}

63C# 2.0&3.0新特性总结
64C# 2.0&3.0新特性总结publicclassGenericMethodTest
65C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
66C# 2.0&3.0新特性总结publicTDisplay<T,V,K>(Tt,Kk,Vv)
67C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
68C# 2.0&3.0新特性总结Console.WriteLine(t.ToString()+""+k.ToString()+""+v.ToString());
69C# 2.0&3.0新特性总结returnt;
70C# 2.0&3.0新特性总结}

71C# 2.0&3.0新特性总结}

72C# 2.0&3.0新特性总结publicclassStudent
73C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
74C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结publicintIDC# 2.0&3.0新特性总结{get;set;}
75C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结publicstringNameC# 2.0&3.0新特性总结{get;set;}
76C# 2.0&3.0新特性总结}

77C# 2.0&3.0新特性总结classProgram
78C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
79C# 2.0&3.0新特性总结staticvoidMain(string[]args)
80C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
81C# 2.0&3.0新特性总结Test<int>t=newTest<int>();
82C# 2.0&3.0新特性总结t.item=10;
83C# 2.0&3.0新特性总结t.Display();
84C# 2.0&3.0新特性总结
85C# 2.0&3.0新特性总结
86C# 2.0&3.0新特性总结Map<string,int>map=newMap<string,int>();
87C# 2.0&3.0新特性总结map.Add("King",23);
88C# 2.0&3.0新特性总结map.Add("XiaoQiang",24);
89C# 2.0&3.0新特性总结map.Display();
90C# 2.0&3.0新特性总结
91C# 2.0&3.0新特性总结ComparableTest<int>test=newComparableTest<int>();
92C# 2.0&3.0新特性总结test.item=123;
93C# 2.0&3.0新特性总结test.Display();
94C# 2.0&3.0新特性总结
95C# 2.0&3.0新特性总结
96C# 2.0&3.0新特性总结//ComparableTest<Student>test2=newComparableTest<Student>();
97C# 2.0&3.0新特性总结
98C# 2.0&3.0新特性总结
99C# 2.0&3.0新特性总结GenericMethodTestg=newGenericMethodTest();
100C# 2.0&3.0新特性总结Console.WriteLine(g.Display(23,32,52));
101C# 2.0&3.0新特性总结
102C# 2.0&3.0新特性总结
103C# 2.0&3.0新特性总结
104C# 2.0&3.0新特性总结Console.ReadLine();
105C# 2.0&3.0新特性总结
106C# 2.0&3.0新特性总结}

107C# 2.0&3.0新特性总结}

108C# 2.0&3.0新特性总结

匿名方法

匿名方法其实就是体现了这样一个原则:如无必要,勿增实体;我们在一个简单的WinForm环境中来说明这个问题:一个按钮单击事件我们可以这样来定义响应代码。

1C# 2.0&3.0新特性总结this.button1.Click+=delegate
2C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
3C# 2.0&3.0新特性总结this.label1.Text="King2002";
4C# 2.0&3.0新特性总结}
;
5C# 2.0&3.0新特性总结
6C# 2.0&3.0新特性总结this.button1.Click+=delegate(objectsender,System.EventArgsarg)
7C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
8C# 2.0&3.0新特性总结this.label1.Text="Test";
9C# 2.0&3.0新特性总结}
;
10C# 2.0&3.0新特性总结this.button1.Click+=newSystem.EventHandler(this.button1_Click);
11C# 2.0&3.0新特性总结privatevoidbutton1_Click(objectsender,EventArgse)
12C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
13C# 2.0&3.0新特性总结MessageBox.Show("Hello");
14C# 2.0&3.0新特性总结}

15C# 2.0&3.0新特性总结
16C# 2.0&3.0新特性总结
17C# 2.0&3.0新特性总结

匿名方法使得代码对于委托的实现更加简单,匿名方法还有一个用途就是操作一些私有成员,因为它相当于共享了一部分代码。

这里会有一个疑问:匿名方法和委托类型的隐式转换有什么要求?答案:只要参数列表和委托类型的返回值是兼容的就可以完成转换。

  • 参数列表兼容:无参数或者参数的数量、类型、修饰符严格匹配
  • 无返回类型,所有return语句形管的表达式可以被隐式转换到委托的类型

后面我们会看到更简单使用delegate的例子。

迭代器

一个对象如果是可枚举的,那么我们可以使用foreach语句来遍历其中的元素。实际上是调用了这个对象的GetEnumberator方法,它返回一个enumberator(枚举器)。实现枚举器很难但是我们可以使用迭代器实现!

1C# 2.0&3.0新特性总结publicclassDaysOfTheWeek:System.Collections.IEnumerable
2C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
3C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结string[]m_Days=C# 2.0&3.0新特性总结{"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
4C# 2.0&3.0新特性总结
5C# 2.0&3.0新特性总结publicSystem.Collections.IEnumeratorGetEnumerator()
6C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
7C# 2.0&3.0新特性总结for(inti=0;i<m_Days.Length;i++)
8C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结C# 2.0&3.0新特性总结{
9C# 2.0&3.0新特性总结yieldreturnm_Days[i];
10C# 2.0&3.0新特性总结}

11C# 2.0&3.0新特性总结}

12C# 2.0&3.0新特性总结