C#3.0新特性:( NET Framework 3.5 與 Visual Studio 2008 )隱式類型、擴展方法、自動實現屬性,對象/集合初始值設定、匿名類型、匿名對象、Lambda,L...

C# 3.0 版和 Visual Studio 2008 一塊兒發佈於 2007 年下半年,但完整的語言功能是在 .NET Framework 3.5 版中發佈的。 此版本標示着 C# 發展過程當中的重大更改。 C# 成爲了真正強大的編程語言。html

1、隱式類型var

  從 Visual C# 3.0 開始,在方法範圍中聲明的變量能夠具備隱式類型var。隱式類型能夠替代任何類型,編譯器自動推斷類型。spring

一、var類型的局部變量必須賦予初始值,包括匿名類(初始值不能爲null)。

var s = 」c#」; var name = new {name=」aa」,age=24};

二、隱式類型的數組

var a = new[]{100};//int[] a=new int[]{1,10,100}
var b = new[]{new[]{1,2,3},new[] {4,5,6}}//交錯數組也可用new[]初始化,不支持隱式類型的多位數組。

三、var 只能做爲局部變量使用,即只能定義在方法內或在屬性get、set訪問器中。還可用於foreach ,for , using語句中。

public string Name { get { var p = new Person();//正確
           return p.Name; } }
for(var i=0;i<10,i++) {} using (var file=new StreamReader(「」) {}

四、var 多數狀況在匿名類型和LINQ中使用。

 string[] words = { "aa", "bb", "cc" }; var upperLower = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() }; foreach (var word in upperLower) { Console.WriteLine(word.Upper+","+ word.Lower); }

2、擴展方法

   使您可以向現有類型「添加」方法,而無需建立新的派生類型。編程

一、最多見的擴展方法是LINQ標準查詢運算符。

    擴展方法向IEnumerable和IEnumerable類型添加查詢功能。c#

int[] ints={10,45,15,39}; var result=ints.OrderBy(g=>g);//擴展方法是一種特殊的靜態方法,但可像擴展類型上的實例方法同樣進行調用。
foreach(var i in result) { Console.Write(i); }

二、對已有的類型進行擴展。

全部的擴展方法寫在一個靜態類中,至關於存放擴展方法的容器。api

全部的擴展方法爲靜態方法。數組

擴展方法的第一個參數this後跟着的類表示要擴展的類型。擴展方法第一個參數後纔是真正的參數列表。app

void Main() { string s = "Hello Extension"; int i = s.WordCount(); Console.WriteLine(i.ToString()); } public static class MyExtensions //全部的擴展方法寫在一個靜態類中,至關於存放擴展方法的容器。
{ public static int WordCount(this String str)//this String表示要擴展的類型。擴展方法第一個參數後纔是真正的參數列表
 { return str.Split(new char[] { ' ', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } }

3、自動實現的屬性

  當屬性訪問器中不須要其餘邏輯時,自動實現的屬性聲明更爲簡潔。編程語言

一、自動實現的屬性必須同時聲明get和set訪問器。

public int One{get;set;}

二、使用private set設置只讀的自動屬性,在定義此屬性的類自己中仍是能夠初始化賦值的。

public string Name{get;private set;}

三、自動實現的屬性不容許具備Attribute屬性。


4、對象/集合初始值設定項

一、對象初始值設定項

  能夠在建立對象時向對象的可訪問字段或屬性賦值,而無需顯示調用構造函數。從 C# 6 開始,除了分配字段和屬性外,對象初始值設定項還能夠設置索引器。函數

例1:簡單應用this

public class Cat { public string name { set; get; } public int age { get; set; } } void Main() { //老式
    Cat x = new Cat(); x.name = "aa"; x.age = 1; //對象初始值設定項
    Cat x1 = new Cat { name = "aa", age = 1 }; Console.Write(x1.age); }

例2:嵌套應用

class Rectangle { public Point P1 { set; get; } public Point P2 { set; get; } public Rectangle() { P1 = new Point(); P2 = new Point(); } }

void Main() { Rectangle myRec = new Rectangle { P1 = new Point() { X = 1, Y = 1 }, P2 = new Point() { X = 200, Y = 200 } }; Console.Write(myRec.P2.Y); } 

二、集合初始值設定項

    無需再代碼中指定對該集合類的多個Add方法調用,編譯器自動添加調用。

集合類必須實現IEumerable。

例1:

List<int> list=new List<int> {0,1,2,3};

例2:

List a = new List { new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 }, new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 } } //若是Add方法容許,能夠將null指定爲其中的一個元素

例三、若是集合支持讀取/寫入索引,能夠指定索引元素。

var numbers = new Dictionary<int, string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };

注意:前面的示例生成調用 Item[TKey] 以設置值的代碼。 從 C# 6 開始,可使用如下語法初始化字典和其餘關聯容器。  它使用具備多個值的對象,此初始值設定項示例調用 Add(TKey, TValue),將這三個項添加到字典中。

var moreNumbers = new Dictionary<int, string> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } };

因爲編譯器生成的方法調用不一樣,這兩種初始化關聯集合的不一樣方法的行爲略有不一樣。 這兩種變量都適用於 Dictionary 類。 其餘類型根據它們的公共 API 可能只支持二者中的一種。

5、匿名類型

匿名類型是編譯器動態建立的一個類,用於存儲一組值。

要建立匿名類型,請使用new關鍵字和對象初始化器,指定類型將包含的屬性和值。

能夠將一組只讀屬性封裝到單個對象中,無需首先定義一個類型。匿名類型只能用於定義它的方法中。

匿名類型由一個或多個公共只讀屬性組成。成員不能用null賦初值。若是多個匿名類型有相同數量和種類的屬性,編譯器將視爲相同的類型,生成多個實例。

var noName = new { name = "a",
age = 1 }; Console.Write(noName.name);

一、匿名類型的屬性名稱能夠從表達式中推斷出來:

int Age = 3; var person = new { Name = "Jack", Age, Age.ToString().Length };

至關於:

var person = new { Name = "Jack", Age = Age, Length = Age.ToString().Length };

二、由匿名類型構成的數組

var anonArray = new[] { new { name = "apple", diam = 4 },
new { name = "grape", diam = 1 }};

生成匿名類型數組

var result = new { pages = 10, Users = from mo in list select new { id = mo.UserId, name = mo.Nick } };

能夠生成:

var result = new { pages = 10, users = new[]{  new{id=1,name="2"}  new{id=2,name="3"} } }

三、由匿名類型構成的列表和字典

var a1 = new List<dynamic>() { new { X = 100, Y = 200 }, new { X = 300, Y = 400} }; Console.Write(a1[1].X); var moreNumbers = new Dictionary<dynamic, dynamic> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } }; Console.Write(moreNumbers[19]);

四、在Linq 中使用

匿名類型一般用在查詢表達式的 Select 子句中,以便返回原序列中每一個對象的屬性子集(Linq 中使用的比較多)。

class MyClass { public string Name { set; get; } public int Number { set; get; } } void Main() { MyClass[] list = new MyClass[12]; var varbj = from obj in list select new { obj.Name,
ID=obj.Number};
    foreach (var v in varbj) { Console.Writ(v.Name, v.ID); } }

五、應用

匿名類型對象的傳遞

void Main() { //匿名類型
    var news = new { title = "冰紅茶", day = "2019-4-10", author = "康師傅" }; ShowInfo(news); } static void ShowInfo<T>(T news) { dynamic d = news; Console.WriteLine(d.title); Console.WriteLine(d.day); Console.WriteLine(d.author); }
用匿名類型填充數組,並計算總年齡
var family = new[]                         //使用隱式類型的數組初始化程序
 { new { Name = "Holly", Age = 37 },      //同一個匿名類型連用5次
            new { Name = "Jon", Age = 36 }, new { Name = "Tom", Age = 9 }, new { Name = "Robin", Age = 6 }, new { Name = "William", Age = 6 } }; int totalAge = 0; foreach (var person in family)  //totalAge累加 對每一個人使用
{ totalAge += person.Age; } Console.WriteLine("Total age: {0}", totalAge);

6、Lambda表示式

(詳細見https://www.cnblogs.com/springsnow/p/9441946.html

  是一個匿名函數,它能夠包含表達式和語句,可用於建立委託或表達式目錄樹類型。

從 C# 1.0 - 3.0委託示例

///  /// C# 1.0 - 3.0 委託的發展過程 /// 
public class DelegateEvlove { //方法1 定義委託
    public delegate void TestDelegate(string s); static void ConsoleStr(string s) { Console.WriteLine(s); } public static void Main(string[] args) { //方法1 實例化委託
        TestDelegate iDelegate = new TestDelegate(ConsoleStr); //方法1 調用委託
        iDelegate("1 instance delgate"); //方法2 匿名委託
        TestDelegate aDelegate = delegate (string s) { Console.WriteLine(s); }; aDelegate("2 anonymous delegate"); //方法3 lambda 表達式
        TestDelegate lDelegate = (s) => { Console.WriteLine(s); }; lDelegate("3 lambda delegate"); } }

一、簡單應用

將λ表達式分配給委託類型,同delegate(int x){retun x*x}(匿名函數)

delegate int del(int i); void Main() { del myDel = x => x * x;//或 x=>{return x*x };
    int j = myDel(5); Console.Write(j); }

二、事件處理程序

當λ表達式有一個輸入參數時,括號是可選的。使用空括號指定0個輸入參數。也能夠顯示指定參數類型

public static event EventHandler myEvent; void Main() { myEvent += (s, e) => { Console.Write(s); }; //即myEvent += delegate(object s,EventArgs e) => { Console.Write(s); }; myEvent(this, null); }

三、建立表達式樹類型

using System.Linq.Expressions; Expression = x=>x*x;

7、Linq表達式

一、簡單應用:

檢索全部Sex爲false的人,查詢結果放到results變量中,results變量與數組persons類型相同

using System.Linq; var persons = new[] { new { Name = "var", Sex = false },
new { Name = "var2", Sex = false } }; var results = from p in persons//
where p.Sex == false
              select p;
 foreach (var person in results) { Console.Write(person.Name); }

二、嵌套成員:

檢索全部城市爲倫敦,且訂單日期爲2018年之後的全部記錄,查詢結果是一個匿名類型的數組。

var customers = new[] { new { Name = "var",City="China" ,Orders  = new []{new{OrderNO=0,OrderDate=new DateTime(2017,1,1)}, new{OrderNO=1,OrderDate=new DateTime(2018,1,1)}, }}, new { Name = "Vicky",City="London" ,Orders  = new []{new{OrderNO=2,OrderDate=new DateTime(2019,9,1)}, new{OrderNO=3,OrderDate=new DateTime(2018,1,1)}, } } }; var someCustomers = from c in customers where c.City == "London" from o in c.Orders where o.OrderDate.Year > 2018 select new { c.Name, o.OrderNO }; foreach (var customer in someCustomers) { Console.Write(customer.Name + customer.OrderNO); }

8、表達式樹

一種有效的數據表達方式,以樹的形式顯示λ表達式。這些全部數據表達方式能夠同時進行編譯。

一、若是操做符被聲明爲能夠接受一個方法委託,則編譯器將生成IL代碼。

public  static IQueryable Where(this IEnumerable source,Func predicate);

二、若是操做符被聲明爲能夠接受一個方法委託「表達式」,則編譯器將生成一個表達式樹。

public  static IQueryable Where(this IQueryable source,Expression > predicate);
相關文章
相關標籤/搜索