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();
}