您的位置:首页 > 编程语言 > C#

【收藏】C# 2.0&3.0新特性总结

2008-04-23 11:06 666 查看

c#2.0新特性

范型

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

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

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

看一段代码:

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

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

public class Test<T>
2
12 public class Map<K, V>
13
29 public class ComparableTest<T> where T : IComparable
30
47 public class MapWithConstraint<K, V> where V : new()
48
64 public class GenericMethodTest
65 public class Student
73 class Program
78

匿名方法

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

1 this.button1.Click += delegate
2
6 this.button1.Click += delegate(object sender, System.EventArgs arg)
7 this.button1.Click += new System.EventHandler(this.button1_Click);
11 private void button1_Click(object sender, EventArgs e)
12
16
17

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

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

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

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

迭代器

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

1 public class DaysOfTheWeek : System.Collections.IEnumerable
2
14 class TestDaysOfTheWeek
15

上面是MSDN上的一个简单的例子,有了直观的印象我们可以深究一点:

迭代器是产生值的有序序列的一个语句块,迭代器不是一种成员,它只是实现函数成员的方式。Yield return语句产生迭代的下一个值 yield break 语句指明迭代已经完成;GetEnumerator返回值只要是枚举器接口或者是可枚举接口(System.Collections.IEnumerable System.Collections.IEnumerator System.Collections.Generic.IEnumerable<T> System.Collections.Generic.IEnumerator<T> ),迭代器就可以被用做函数体。

不完整类型
不完整类型完全是为了更好的进行代码管理。仔细观察我们现在添加一个页面时,它的后代代码就使用了不完整类型:

public partial class _Default : System.Web.UI.Page

c#3.0新特性

自动实现属性
Auto-Implemented Properties

1public class Card
2
3
13 class Customer
14
15

IEnumerable<int> ints = from item in items

where item > 2.5

select item;

foreach (var p in ints)

隐式类型变量
Implicitly Typed Variables (var)

内部变量的类型可以使用var而不是确切的类型。var关键字可以指示编译器通过右侧的初始化部分来推断实际的数据类型。

var num = 5;

// anon 被编译成匿名类型 注意下面的Name Age都没有定义

var list = new List<int>();

using (var file = new System.IO.StreamReader(@"D:\http.txt", Encoding.Default))

var的使用会有一些约束:<ms-help://MS.MSDNQTR.v90.en/dv_csref/html/b9218fb2-ef5d-4814-8a8e-2bc29b0bbc9b.htm>

对象、集合初始化

Object and Collection Initializers

设计完成之后生成了一些类代码,但是这里有一个问题就是属性代码的填写,在FX3.0属性代码的已经简化,

类的初始化也提供了更简单的书写方式;可以看一下下面代码段中c2的初始化,列表对象的初始化按照同样的格式也会大大的简化。

1public class Card
2
3
13 class Program
14
15
87

匿名类型

Anonymous Types

匿名类型把一系列的只读属性封装在一个对象里面,而并没有指定这个对象的类型编译器会给这个对象类型一个名字,但是这个名字在代码级别是不可用的。

看下面的代码:

// anon 被编译成匿名类型 注意下面的Name Age都没有定义

var anon = new { Name = "Terry", Age = 34 };

//anon.Age = 23;

最后一行如果执行编译器会给出一个错误:

Property or indexer 'AnonymousType#1.Age' cannot be assigned to -- it is read only

这个错误信息可以印证上面的说法。继续扩展上面的代码,一起看:

var card = from c3 in cards

where c3.ID > 13

//select c3;

foreach (var item in card )

这里的代码是匿名类型的一个典型应用,详细请查阅:

<ms-help://MS.MSDNQTR.v90.en/dv_csref/html/59c9d7a4-3b0e-475e-b620-0ab86c088e9b.htm>

扩展方法

Extension Methods

扩展方法是一个静态方法,可以关联在一种类型上,所以这个方法可以在他处调用。这样仿佛给某一个类型添加了方法!而实际上我们并没有改变原有的代码。

详情参阅:ms-help://MS.MSDNQTR.v90.en/dv_csref/html/175ce3ff-9bbf-4e64-8421-faeb81a0bb51.htm

public static class Test

{

public static string RemoveWhiteSpace(this string s)

{

return s.Replace(" ", "");

}

}

定义了上面的方法之后,我们可以在string类型上使用这个方法下面是在开发环境中的截图:

delegate void Testdelegate(string s);
2
3 static void Show(string s)
4
5
11 //1.1里面我们这样做
12
13 Testdelegate t = new Testdelegate(Show);
14
15
16
17 //2.0
18
19
21
22
23 //3.0
24
25
27 t("Kingtest1");
28
29 t2("20022396");
30
31 t3("20022458");
32

在3.0里面我们的代码使用了Lambda表达式,详情参阅:

ms-help://MS.MSDNQTR.v90.en/dv_csref/html/57e3ba27-9a82-4067-aca7-5ca446b7bf93.htm

Lambada表达式在C#3.0中的典型应用:

ms-help://MS.MSDNQTR.v90.en/fxref_system.core/html/5a7a3466-7d99-dea6-a9fa-04043f951573.htm

// Split the string into individual words.

string[] words = sentence.Split(' ');

// Prepend each word to the beginning of the

// new sentence to reverse the word order.

string reversed = words.Aggregate((workingSentence, next) =>

next + " " + workingSentence);

bool b = words.All(w => w.Length > 5);

bool b2 = words.Any(w => w.Length > 10);

一句话体会:

c#新特性的应用需要我们深入的学习以及在团队范围内的知识共享,这样才不致于让代码显得怪异

From:http://www.cnblogs.com/me-sa/archive/2008/04/23/1166688.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: