Visual Studio 2008开发新特性系列课程(2):C#3.0与VB9.0的新特性介绍

来源:互联网 发布:服务器挂淘客软件 编辑:程序博客网 时间:2024/05/16 05:03

C# 3.0新特性

是语言层次的改进(CLR没有改变),可以说主要是为了Linq才对其进行改进的。

1. 隐式类型化本地变量
在一个隐式类型化的本地变量和声明中,本地变量类型的声明过程是由使用的表达式初始化变量来推断的。当一个本地变量声明标示为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>();

? 声明者必须包含一个构造者。
? 这个构造器必须是一个表达式。这个构造器不能够是一个对象或者构造器集合的自身,但是它可以是一个新的包含一个对象或者构造器集合的表达式。
? 在编译时刻构造器表达式的类型不能为null类型。
? 如果本地变量声明包含多种构造器,那么构造器必须都具有相同的编译时类型。

 

2.自动属性
自动属性允许你避免手工声明一个私有成员变量以及编写get/set逻辑,取而代之的是,编译器会自动为你生成一个私有变量和默认的get/set 操作。
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}

 

3.对象初始化器和集合初始化器
public class user
{
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public int Age { get; set; }
 private int test01 = 25;
 internal int test02;
 Public user()
 {
  Age = .....//构造函数
 }
}
class Program
{
 static void Main(string[] args)
 {
 //对象初始化器,不能初始化私有类型变量,也可以和构造函数一起使用
 user person = new user { FirstName = "Scott", LastName = "Guthrie", test02 = 56 };
 Console.WriteLine(person.test02);
 Console.WriteLine(person.Age);
 
 List<user> myusers = new List<user>
 {
  new user(){ FirstName = "Scott", LastName = "Guthrie", test02 = 56 }, //不能操作test01
  new user(){ FirstName = "Dick", LastName = "Cheney", test02 = 57 }
 }


 Console.ReadLine();
 }
}
说明:
? 可以和构造函数一起使用
? 允许部分赋值
? 允许给internal成员赋值
? 构造函数比对象初始化器先执行(构造函数先执行,也就是先执行user(),然后,才执行对象初始化构造器new user{......})。

 

4.匿名类型
? C#3.0 允许新的操作符被用来作为匿名对象构造器以建立匿名类型的对象
? 匿名类型是没有名称的类类型,它直接继承于object

var p1 = new { Name = "西瓜", Price = 495.00 };
var p2 = new { Name = "苹果", Price = 26.95 };
p1 = p2; //编译器可以自动判断p1和p2是同一类型的
Console.WriteLine("name:" + p1.Name + " price=" + p1.Price);
Console.ReadLine();

 

5.分部方法
在定义分部方法时,值得注意的是:
1、分部方法必须声明在分部类型(partial class)中;
2、分部方法使用partial修饰符;
3、分部方法并不是总有方法体(body,即方法的实现);
4、分部方法必须返回void;
5、分部方法可以是静态的(即使用static 修饰符);
6、分部方法可以包含参数(包括在参数中使用this、ref 和params 修饰符,不支持out 修饰符,可以使用ref 修饰符来代替它);
7、分部方法必须是私有方法(private)

    partial class PM
    {
        static void Main(string[] args)
        {
            int i = 9;
            PM.M(i=1);

            Console.WriteLine(i);
            Console.ReadLine();
          }
    }

    partial class PM //分部方法必须声明在分部类型(partial class)中
    {
        static partial void M(int i);//分部方法使用partial修饰符,必须返回void    
    }
  
    // This part can be in a separate file.
    partial class PM //分部方法必须声明在分部类型(partial class)中
    {
        // Comment out this method and the program will still compile.
        //如果没有改方法的实现,调用分部方法的时候( PM.M(i=1);),就不会发生作用。
        static partial void M(int i)
        {
        }
    }
分部方法是一些方法,它使轻量级的事件处理成为可行。
基本思路:定义一些事件,对于这些事件的函数就采用分部方法进行处理,如果这些方法存在实现,则这些事件会执行,否则,这些事件不会执行。

 

6.扩展方法
? 可以在不改变类的方法时,添加新的方法,但是不能改变原来的方法。
? Extension Method仅仅是看起来像是一个类型的方法,但其实质上不是,它更像是静态类型的静态方法,事实上,它确实拥有静态方法所具有的所有功能
? Extension Method的作用域是整个namespace可见的,并且可以通过using namespace来导入其它命名空间中的Extension Method。
class test
{
}

static class extension //static class extension
{
//扩展方法不能访问原类中的成员变量,主要用来对常用类的功能扩展
 public static void add(this test m)//this 关键字  test 需要扩展的类名
 {
 Console.WriteLine("add....");
 }
}

 

7. Linq表达式和表达式树
C#2.0 引入了匿名函数,它允许代码块能够被写成“内联”在代理值所期望的地方。当匿名函数提供功能性编程语言的巨大威力的同时,匿名函数的标记也显得相当的冗长。Lambda表达式提供了更简明的功能性标记来书写匿名函数。

--Lambda表达式书写为一组参数列表,紧接着=>标记,然后跟随某个表达式或声明块
--Lambda表达式的参数可以是显式的或者隐式的类型。在一个显式类型参数列表中,每个参数的类型都必须显式声明。
--表达式树允许lambda表达式能够代表数据结构替代表示为执行代码

public static void Query()
{
 Dictionary<string, int> students = new Dictionary<string, int>();
 students.Add("litao", 24);
 students.Add("yanghua", 21);
 students.Add("zhangchao", 22);
 IEnumerable<KeyValuePair<string, int>> queryResult = from student in students
           where student.Value <= 23
           orderby student.Value descending
            select student;
 foreach (var student in queryResult)
 {
  Console.WriteLine(student.Key + " is " + student.Value + " years old.");
 }
  Console.ReadLine();
}