VS08新特性之C# 3.0 新语法

来源:互联网 发布:阿里云ubuntu饥荒联机 编辑:程序博客网 时间:2024/06/05 02:52

 C# 3.0 新语法

 

C# 3.0 概述
C# 3.0 于 2008 年初随 VS2008 一起正式发布。

C# 的进化
C# 1.0——托管代码
C# 2.0——泛型,匿名方法
C# 3.0——LINQ,Lambda

C# 3.0 概述
C# 3.0 的新特性包括
自动属性、推断类型、匿名类、扩展方法、对象初始化器、集合初始化器、Lambda 表达式、LINQ

——自动属性
普通类:
class Person
    {
        private string firstName;
        private string lastName;
        private int age;

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
    }
使用了自动属性的类:
class PersonNew
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
演示示例:自动属性


——自动属性本质
使用了自动属性的类,编译器为我们自动生成了这些私有变量
在反汇编后,两者的代码几乎完全一样。

自动属性小结:
自动属性的典型适用场合:
在属性代码中只包含基本的赋值取值功能
简单的实体类

使用自动属性时,需要注意以下几点:
自动属性不能实现只读或者只写属性
因为没有声明私有变量,你在使用自动属性时只能直接使用属性名进行引用

——对象初始化器
传统赋值方式
// ….
Person lincoln = new Person();
lincoln.FirstName = "Lincoln";
lincoln.LastName = "Burrows";
lincoln.Age = 30;

lincoln.SayHi();
// ….

使用对象初始化器赋值
// ….
Person scofield = new Person {
    FirstName = "Michael",
    LastName = "Scofield",
    Age = 20 };

scofield.SayHi();
// ….
演示示例:对象初始化器

——可嵌套的对象初始化器
//可嵌套的对象初始化器
Person tbag = new Person
{
    FirstName = "Theodore ",
    LastName = "Bagwell",
    Age = 32,
    Address = new Address
    {
        Street = "Prison SONA",
        Country = "Panama"
    }
};
对象初始化器不仅可以包含简单的赋值代码,还可以包含其他的对象初始化器,即嵌套的对象初始化器

——对象初始化器小结
请指出以下代码中的错误:
Person scofield = new Person
(
    FirstName = "Michael";
    LastName = "Scofield";
    Age = 22;
    Address = new Address
    (
        Street = "Prison SONA";
        Country = "Panama";
   )
);
对象初始化器中
() 应该改为 {}
; 应该改为 ,
Person scofield = new Person
{
    FirstName = "Michael",
    LastName = "Scofield",
    Age = 22,
    Address = new Address
    {
        Street = "Prison SONA",
        Country = "Panama",
   }
};

——集合初始化器
集合初始化器使我们可以象初始化数组那样初始化集合
传统赋值方式
List<string> foxRiver8 =
                     new List<string>();
foxRiver8.Add("Michael");
foxRiver8.Add("Lincoln");
foxRiver8.Add("Sucre");
foxRiver8.Add("Abruzzi");
foxRiver8.Add("T-Bag");
foxRiver8.Add("C-Note");
foxRiver8.Add("Tweener");
foxRiver8.Add("Charles");
使用集合初始化器赋值
List<string> foxRiver8 =
                      new List<string>{
    "Michael",
    "Lincoln",
    "Sucre",
    "Abruzzi",
    "T-Bag",
    "C-Note",
    "Tweener",
    "Charles"
};
演示示例:集合初始化器

问题
小艾同学从网上下载了一个图形类库(只有DLL,没有源代码),感觉非常好用。但是,其中的 Rectangle 类只有一个计算面积的方法。现在小艾想为它添加一个计算周长的方法,大家帮忙想想看,有什么好办法呢?
扩展方法

——简单的扩展方法
先看一个简单的例子
string greeting = "welcome to beijing";
greeting.SayHi();
字符串类型什么时候多了一个 SayHi() 方法?演示示例:简单的扩展方法

代码分析:
定义扩展方法
//using …..
namespace HelloOrcas
{
    static class JBUtility//static:扩展方法必须在静态类中定义
    {
//扩展方法是一种特殊的静态方法 static;
//第一个参数前加关键字 this;
//这里的 string 表示将要为所有的 string 类型添加扩展方法
        public static void SayHi(this string s)

        {
            string message = string.Format(
             "Hi, 我是一个字符串,我的值是: /"{0}/"。", s);
            MessageBox.Show(message, "JBUtility",
                MessageBoxButtons.OKCancel,
                MessageBoxIcon.Information);
        }
    }
}

注意回顾 静态方法 和 静态类 概念,可以通过提问总结 this 出现的场合 例如 索引器

——定义扩展方法的语法
语法:不带参数的扩展方法:
static 方法名 (this 目标类型 参数名)
语法:带参数的扩展方法:
static 方法名 (this 目标类型 参数名,参数类型1,参数名1,… …. )

——扩展方法的使用:
使用扩展方法时,请注意:
在一个静态类中定义需要的扩展方法
如果上面定义的扩展方法位于不同的命名空间,使用时记住用 using 语句引用过来
当类本身的方法与扩展方法同名时,优先类本身的方法

——带参数的扩展方法示例:
定义带参数的扩展方法
public static void SayHi(this string s, string caption)
{
    string message = string.Format(
    "Hi, 我是一个字符串,我的值是: /"{0}/"。", s);
    MessageBox.Show(message, caption,
        MessageBoxButtons.OKCancel,
        MessageBoxIcon.Information);
}

调用带参数的扩展方法
string greeting = "welcome to beijing";
greeting.SayHi("Beijing 2008");

演示示例:带参数的扩展方法

现场编程:
请编写 string 类的扩展方法将字符串转换为 Pascal
大小写格式,要求运行如下代码:
string greeting = "welcome to beijing";
Console.WriteLine(greeting.ToPascal());
输出 WelcomeToBeijing

//参考答案
public static string ToPascal(this string s)
{
    string[] words = s.Split(new char[] { ' ' });
    string result = string.Empty;

    foreach (string word in words)
    {
        result += word.Substring(0, 1).ToUpper() +
            word.Substring(1).ToLower();
    }
    return result;
}

——扩展方法小结
使用扩展方法时,需要注意以下几点:
扩展方法允许我们对已存在类型的行为进行扩展
扩展方法是一种特殊的静态方法
扩展方法必须在静态类中定义
扩展方法的优先级低于同名的类方法
扩展方法只在特定的命名空间内有效
除非必须不要滥用扩展方法
(使用扩展方法要适度。
过度地使用扩展方法可能造成类的结构变得复杂,行为不可预知
原则上,如果可以写到类本身代码中的方法就不要做成扩展方法)

——var关键字
var是C# 3.0 引入的一个新关键字,它可以根据初始值自动推断局部变量类型。
使用 var 语法:
var i = 2008;
var s = "ACCP";
var d = 5.0;
var numbers = new int[] {1, 2, 3};
var students = new Dictionary<int, Person>();
传统方式:
int i = 2008;
string s = "ACCP";
double d = 5.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int, Person > students =
 new Dictionary<int, Person >();
两者效果完全一样。
(事实上伴随 var 关键字引入的是一种叫做 “Implicitly Typed Local Variables” 的机制
即 “暗示类型局部变量” 注意 在这里 它清晰地表明 var 修饰的是一个局部变量
所以虽然我们后面有时称呼它为“推断类型” 但实际上它不是一种“类型” 而是“可以推断类型的局部变量”)

——var 与 object 的区别
使用 var:
var name = "Beijing";
name = 2008;
编译错误!
Cannot implicitly convert type 'int' to 'string'

使用 object:
object name = "Beijing";
name = 2008;
可以通过编译'
演示示例:var与object的区别

——匿名类
var p=new{
 Name="Tin Tin",
 Age=20,
 Gender="male"};
Console.WriteLine(p.Name);//虽然是匿名类型,但是因为还是强类型,所以仍能很好地支持智能感应
演示示例:匿名类

——匿名类的本质
编译器自动生成的匿名类名称

——var小结
请判断以下代码的对错
var x;
错误, 必须初始化
var y = {1, 2, 3}; 
错误, 应改为 var x = new int[] { 1, 2, 3 };
Int i;
var v = i++;
错误, 变量 i 必须先初始化
var z = null;
错误, 初始化值不允许为null

——var小结
使用关键字 var 时,需要注意以下几点:
定义变量时,必须同时完成初始化工作
不允许用 var 定义一个以 null 值初始化的局部变量
var 本身不是一个新类型,本质上,它只是用来修饰一个可以推断出类型的局部变量

——总结
请说出三条以上 C# 3.0 的新特性。
使用 var 和 object 声明变量时有什么区别?
引入扩展方法有什么好处?

原创粉丝点击