C#2.0 语言特性
范型Generics
使类或方法获得类型参数变得功能强大。
委托Delegates
可以封装一个或多个方法的类,可以理解为方法的接口
delegate void SimpleDelegate();
delegate int ReturnValueDelegate();
delegate void TwoParamsDelegate( string name, int age );
//Delegate instantiation (C# 1.x)
public class DemoDelegate
{
}
//Delegate instantiation (C# 2.0)
public class DemoDelegate
{
}
匿名方法Anonymous Methods
允许我们定义委托对象可以接受的代码块。这个功能省去我们创建委托时想要传递给一个委托的小型代码块的一个额外的步骤
delegate void SimpleDelegate();
public class DemoDelegate
{
}
不使用匿名方法则需要
public class Writer {
}
public class DemoDelegate
{
}
迭代器和Enumerators and Yield
迭代器是一种方法、get访问器或运算符,使得开发人员能在类或结构中支持foreach迭代,而不必实现实现整个 IEnumerator接口
迭代器特点:
迭代器是可以返回相同类型的值的有序序列的一段代码。
迭代器可用作方法、运算符或 get 访问器的代码体。
迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。
可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用
迭代器的返回类型必须为
IEnumeable ,IEnumerator,IEnumeable <T>,IEnumerator<T>
实现代码:
class StudentList
{
string student1 = "甲";
string student2 = "乙";
string student3 = "丙";
string student4 = "丁";
string student5 = "戊";
public string Student1
{
get{return student1;}
set{student1 = value;}
}
public string Student2
{
get{ return student2;}
set{student2 = value;}
}
public string Student3
{
get{return student3;}
set{student3 = value;}
}
public string Student4
{
get{ return student4; }
set{ student4 = value;}
}
public string Student5
{
get { return student5; }
set { student5 = value; }
}
//编写该类的迭代器(实现System.Collections.IEnumerator 接口)
public System.Collections.IEnumerator GetEnumerator()
{
//通过for循环对StudentList类中的5个string类型变量进行处理
for(int i=0;i<5;i++)
{
switch (i)
{
case 0:
yield return student1;
break;
case 1:
yield return student2;
break;
case 2:
yield return student3;
break;
case 3:
yield return student4;
break;
case 4:
yield return student5;
break;
}
}
}
}
在main函数中:
//通过foreach使用迭代器获得StudentList对象中的字段值
StudentList myStudentList = new StudentList();
foreach (object student in myStudentList)
{
Console.WriteLine(student.ToString());
}
C#3.0语言特性
局部类型推导Local Type Inference
定义可变类型变量
var x = 2.3;
var s = "sample";
Lambda表达式
allow the definition of anonymous methods using more concise syntax.
所有的Lambda式都使用操作符“=>“,表示“goes to (转变为)”。
操作符左边部分是输入参数表,右边部分是表达式或语句块。x => x * x 读成“x转变为x 乘x”。
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
扩展方法Extension Methods
C#是一种面向对象的编程语言,允许通过继承扩展类。但是,设计一个类可以安全的继承并且将来可以很好的维护是很难的。除非类被设计为可被继承的,可以通过申明类为sealed。但是这样安全性就与灵活性冲突。
C# 3.0 introduces a syntax that conceptually extends an existing type (either reference or value) by adding new methods without deriving it into a new type.
//传统方法
static class Traditional
{
}
//扩展方法
static class ExtensionMethods
{
}
对象初始化表达式Object Initialization Expressions
C# 3.0 introduces a shorter form of object initialization syntax that generates functionally equivalent code。
C# 3.0 使用更短的对象初始化语法,这种语法同样可以实现对象的初始化。
//传统方法
Customer customer = new Customer();
customer.Name = "Marco";
customer.Country = "Italy";
//使用Object Initialization Expressions
Customer customer = new Customer { Name = "Marco", Country = "Italy" };
匿名类型Anonymous Types
An object initializer can also be used without specifying the class that will be created with the new operator. Doing that, a new class-an anonymous type-is created.
可以使用new操作符在不声明类型的情况下即可初始一个对象。这就是匿名方法。
Customer c1 = new Customer { Name = "Marco" };
var c2 = new Customer { Name = "Paolo" };
var c3 = new { Name = "Tom", Age = 31 };
var c4 = new { c2.Name, c2.Age };
var c5 = new { c1.Name, c1.Country };
var c6 = new { c1.Country, c1.Name };
变量c1,c2是Customer类型,c4,c5,c6没有声明类型。但是可以从代码的上下文中推出c4,c5,c6为Customer类型。
查询表达式Query Expressions
C# 3.0 also introduces query expression_rs, which have a syntax similar to the SQL language and are used to manipulate data. This syntax is converted into regular C# 3.0 syntax that makes use of specific classes, methods, and interfaces that are part of the LINQ libraries. We would not cover all the keywords in detail because it is beyond the scope of this chapter. We will cover the syntax of query expression_rs in more detail in Chapter 4, “LINQ Syntax Fundamentals.”
In this section, we want to introduce the transformation that the compiler applies to a query expression_r, just to describe how the code is interpreted.
Here is a typical LINQ query:
// Declaration and initialization of an array of anonymous types
var customers = new []{
};
foreach( var x in query ) {
}
A query expression_r begins with a from clause (in C#, all query expression_r keywords are case sensitive) and ends with either a select or group clause. The from clause specifies the object on which LINQ operations are applied, which must be an instance of a class that implements the IEnumerable<T> interface.
That code produces the following results:
{ Name = Tom, Perc = 0.035 }
{ Name = Marco, Perc = 0.045 }
C# 3.0 interprets the query assignment as if it was written in this way:
var query = customers