從頭學(xué)C# 7(筆記)


數(shù)據(jù)類型

具有某種數(shù)據(jù)類型的數(shù)據(jù),稱為這個數(shù)據(jù)類型的實例。如學(xué)生是類型,王小二是實例。
類型可以擁有自己的成員(屬性和方法等)。 類型type指的是類、結(jié)構(gòu)、接口、委托、枚舉。
C#的類型包括值類型和引用類型,其中重要的類型定義成基元類型。
C#的預(yù)定義類型:8種整數(shù)型,2種2進質(zhì)浮點型,1種金融十進制浮點型,1種布爾型,1種字符型。

  • 值類型 堆
int long char double datetime 屬于結(jié)構(gòu) 枚舉emnu
  • 引用類型 棧
string class 接口 委托
引用類型只可以為null,值類型不可以
string str=null;
string str1='//n';//轉(zhuǎn)義

實際對象的計算機語言表示,擁有許多成員,最重要的是屬性和方法。
對象是類的實例
屬性存儲信息和數(shù)據(jù)
方法是供我們可用的函數(shù)

運算符和分支結(jié)構(gòu)

  • 運算符
//一元運算符
+ - ++ --
int i=i++  i=i-- //放后是執(zhí)行完再加一
//二元運算符
+ - * / %
== != < > <= >= //關(guān)系運算
&& ||
+= -= *= /= %=
//三元運算符
? :
//運算符重載

//分支結(jié)構(gòu)
if else
switch case

方法與參數(shù)

方法method

用來把一些相關(guān)的語句收集在一起的代碼塊。方法必須有方法名,擁有0個或多個參數(shù),可以有0或1個輸出,C#7后可以有多個輸出,在這之前借助Out關(guān)鍵字實現(xiàn)多輸出。
一般定義不返回函數(shù)值得叫方法,返回值的叫函數(shù)。
C#所有數(shù)據(jù)結(jié)構(gòu):類 結(jié)構(gòu) 接口,可以有方法。 枚舉 不可以寫方法,委托的方法是固定的不可以自定義

方法的定義/簽名signature

  • 修飾詞 public protected internal private
  • 方法的返回類型。void
  • 方法名稱
  • 方法參數(shù)
  • 實際參數(shù)和形式參數(shù)
  • 按值傳遞和按引用傳遞ref
  • out關(guān)鍵字的使用
  • 可變關(guān)鍵字 params 數(shù)組傳參 必須在最后
//定義
public int a(params int[] b){
    return 0;
}
//調(diào)用
a(1,2,3)//可變長度
  • 可選參數(shù)
  • 命名參數(shù)
  • 遞歸調(diào)用recursion

數(shù)組與循環(huán)

  • Array a =new int[10]
  • 索引 從0開始 索引循環(huán)的類型是一致的
  • 一維數(shù)組
  • 二維數(shù)組 交錯/齒輪數(shù)組
  • 循環(huán) for foreach
  • while和do while

面向?qū)ο蠛皖?/h2>
  • 面向?qū)ο?object oriented
  • 封裝集成多態(tài)
  • 類里包括:
    常量const、字段field、屬性property、構(gòu)造函數(shù)、析構(gòu)函數(shù)、自定義方法、嵌套類
  • 構(gòu)造函數(shù) construct
    當(dāng)使用new關(guān)鍵字時,自動調(diào)用構(gòu)造函數(shù),構(gòu)造函數(shù)名稱與類相同,public,無返回值。構(gòu)造函數(shù)可以是private(單例模式)
public class car{
    public colors color{
        get{
            return this;
        }
        //set打開后,get也要打開
        };
        set{
           this=value;//默認(rèn)value
        };
    }
}
  • 對象初始化器
  • 靜態(tài)成員
    靜態(tài)方法只能使用靜態(tài)字段和屬性。
    靜態(tài)成員無需實例化即可使用。
    靜態(tài)成員屬于類而非類的實例,但被所有類共享。
    實例的方法可以使用靜態(tài)和實例字段和屬性。
  • 靜態(tài)構(gòu)造函數(shù)
    當(dāng)你的類中有靜態(tài)函數(shù),C#默認(rèn)會創(chuàng)建一個靜態(tài)構(gòu)造函數(shù),為你的靜態(tài)成員賦值,不能有修飾詞,不能有輸入和輸出。靜態(tài)構(gòu)造函數(shù)只調(diào)用一次。

結(jié)構(gòu)

  • 結(jié)構(gòu)是值類型,可以被看作是輕量級的類
  • 設(shè)計結(jié)構(gòu)是為了提升程序的性能:
    引用用類型內(nèi)存的初始化需要牽扯到堆上內(nèi)存的分配,因此如果一個自定義的類型==只會包括值類型作為成員==,使用結(jié)構(gòu)是一個較好的選擇
  • C#自帶的結(jié)構(gòu)有很多,包括int,DateTime等,它們的成員==全部是值類型==。
  • 結(jié)構(gòu)可以有自己的方法
  • 結(jié)構(gòu)的成員最好是值類型

繼承inheritance

  • 所有類繼承于System.Object Get.Type(反射)
  • private 只用自己能訪問
  • protected 自已和子類
  • this當(dāng)前類型,可以用this呼叫其它構(gòu)造函數(shù),Base調(diào)用基類構(gòu)造函數(shù)
  • 實例化對象會一層一層,執(zhí)行到System.Object基類
  • 方法的重寫override、重載overload、隱藏
    • 方法隱藏,子類和父類方法名稱相同,自動隱藏,子類可以用new關(guān)鍵字
    • 方法重寫,子類和父類擁有相同的簽名方法,但子類希望得到不同的行為,而且父類的方法是虛方法或抽象方法。
    • 方法重載,子類和父類有相同的方法名稱,但簽名不同。
  • 密封類sealed:
    • sealed修飾類型,不能補繼承
    • sealed修飾方法,不能被重寫
    • 結(jié)構(gòu)是密封類型,不能被繼承
  • 抽象類abstract:必須被繼承的類
    • 無法實例化一個abstract,子類必須用override來重寫它
    • 不能與sealed修飾
    • 比較虛的概念使用abstract
    • abstract可以有普通的方法,也可以有抽象方法
    • 接口-特殊的抽象類,只能有抽象方法
  • 抽象方法
    • 抽象方法本身沒有方法體,待子類去實現(xiàn)
    • 抽象方法必須在抽象類中
  • 虛方法virtual
    • virtual可以有方法實體,也可以沒有
    • 子類可以重寫,也可以不重寫
    • 用于父類可以實現(xiàn),但子類有不同實現(xiàn)方式的情景
public class a{
    int x;
    int y;
    public a(){}
    public a(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class b:a{
    public b(int x,int y):base(x,y){}
}

多態(tài)和接口

  • 多態(tài) polymorphims
    • 一個類型有多種狀態(tài)。
  • 接口 interface
    • 接口是一種特殊的類,方法只能有簽名,而不能有方法體。
    • 使用借口實現(xiàn)has-a關(guān)系。
    • 使用接口實現(xiàn)多重繼承,解決單一繼承的缺陷。
    • 接口就像技能,通過多重繼承賦予不同的技能。
  • 策略模式
    • ==依賴注入==

第三部分 數(shù)據(jù)結(jié)構(gòu)

  • C# 2.0 泛型
  • C# 3.0 linq
  • C# 4.0 動態(tài)語言

集和與泛型

  • 數(shù)據(jù)結(jié)構(gòu) Data Sturcture
    • 數(shù)據(jù)結(jié)構(gòu)是以某種形式將數(shù)據(jù)組織在一起的集合,它不僅存儲數(shù)據(jù),還支持訪問和處理數(shù)據(jù)的操作。
    • 簡單分類:線性表,鏈表,哈希表,樹,圖等
    • 大部分編程語言都可以實現(xiàn)這些數(shù)據(jù)結(jié)構(gòu),C#已經(jīng)為我們實現(xiàn)了一部分,例如線性表(Array,List,ArrayList,Stack,Queue),鏈表(LinkedList),哈希表(HashTable,Dictionary)等等
    • C#中的集合對應(yīng)了一些數(shù)據(jù)結(jié)構(gòu)
  • 集合 collection
    • 包括泛型集合與非泛型集合,它們都是不定長的
    • 非泛型集合:集合里的元素可以為任意的類型
    • 泛型集合:集合里的元素只可以為一種類型T
    • 從定義上,數(shù)組(Array)不是集合因為它是定長的
  • 非泛型集合
    • ArrayList
    • Stack 棧
      • 后進先出(LIFO)
      • 棧是限制插入和刪除只能在一個位置上進行的線性表,該位置是表的末端,叫作棧頂,對棧的基本操作有push(進棧)和pop(出棧),前者相當(dāng)于插入,后者相當(dāng)于刪除最后一個元素
      • 練習(xí):棧中全是int,找出棧中最小的元素
    • Queue 隊列
      • 先進先出(FIFO)
      • 隊列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進行刪除操作,而在表的后端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。
    • 裝箱boxing與拆箱unboxing
      -非泛型集合的兩個問題:造成裝箱和拆箱\類型不安全
      • 裝箱的定義:將值類型分配給object變量
      • 拆箱的定義:將object變量中的值賦給一個值類型
      • 拆箱有風(fēng)險,操作需謹(jǐn)慎
  • 泛型集合
    • 泛型集合List<T>
    • T稱為類型參數(shù)或占位符
    • 實際使用時必須為T指定一個具體類型,例如int,string等,稱為實際參數(shù)
    • 棧和隊列的泛型版本
    • 由于性能和類型安全,出現(xiàn)泛型后以經(jīng)沒有人使用非泛型合集
  • 泛型方法
    • 泛型方法:輸入輸出參數(shù)包括了類型參數(shù)
    • 例如:交換任意兩個同類型變量的值
    • 使用泛型方法可以達到代碼復(fù)用的目的
  • 泛型類型
    • 可以自定義泛型結(jié)構(gòu)和類
    • 例如,創(chuàng)建一個自定義的泛型結(jié)構(gòu)
  • 泛型約束
    • 泛型約束使得類型參數(shù)T只能是滿足某種條件的類型
    • 接口約束:使得泛型的實際參數(shù)必須實現(xiàn)某個接口
    • 基類型約束:實參必須是某個類的派生類
    • 構(gòu)造函數(shù)約束:泛型實參必須具有可訪問的無參構(gòu)造函數(shù)(默認(rèn)的也可)
public a<T,K>(T b,K c) where T: new() where K:struct
  • 可空類型
    • 定義為Nullable<T> 或者用?
    • 一個結(jié)構(gòu),使用HasValue()判斷是否有值

算法介紹

  • 算法 algorithm
    • 定義 有限步操作的集合
    • 有線性、確切性、輸入、輸出、可行性
    • 時間復(fù)雜度O(S)和空間復(fù)雜度n(S)
  • 常用數(shù)據(jù)結(jié)構(gòu)
    • 線性列表
      • array 定長 類型安全
      • arrayList 非泛型 數(shù)據(jù)類型不安全
      • List<T> 泛型
    • 鏈表
      • 定義:包括節(jié)點和下一個借點的引用。在內(nèi)存中不連續(xù)。
      • 雙向鏈表則還包括前一個節(jié)點的引用。
      • 好處:節(jié)省內(nèi)存空間,中間插入和刪除的時間復(fù)雜度底。(常數(shù)復(fù)雜度,線性列表為線性)
      • 壞處:不能按索引器訪問
        -哈希表 hashtable
        -哈希表是鍵值對數(shù)據(jù)結(jié)構(gòu)key value
        -哈希函數(shù)和哈希碰撞(解決哈希碰撞,線性尋址法,平方尋址法)
      • 插入和刪除的時間復(fù)雜度都是常數(shù),但哈希表不能排序。
      • 節(jié)省空間,速度快
      • hashtable非泛型
      • Dictionary<K,T>

CLR(公共語言運行時)

  • .net框架主要成員
  • 兩部編譯和跨平臺
    -中間語言IL,c#通過csc.EXE,先編譯為中間語言,在運行時,CLR通過JIT即使編譯為機器碼。

委托和事件

  • 委托 delegate

    • 委托是一個特殊的類,是密封袋,不可以繼承。包括一個特殊的方法invoke,也可以看成一個簽名。
    • 使用委托傳入方法,起到代碼復(fù)用的目的
    • 可以為委托提供特殊的簽名方法
  • 委托的原理:

    • 委托是一個密封類,它繼承自System.MulticastDelegate,后者再繼承自System.Delegate
      這個類的成員是固定的,這個密封類包括一個構(gòu)造函數(shù)和三個核心函數(shù),Invoke方法賦予其同步訪問的能力,BeginInvoke,EndInvoke賦予其異步訪問的能力
    • 委托鏈:
      • System.MulticastDelegate是所有委托的父類,它含有一個非常重要的字段_invocationList,指的是委托自身的方法鏈,它是一個Delegate類型的數(shù)組,所以委托可以掛接多于一個函數(shù)(即一個函數(shù)List),可以為這個鏈自由的添加或刪除函數(shù)。
      • 一個委托鏈可以沒有函數(shù)如果執(zhí)行委托,將會順序的執(zhí)行委托鏈上所有的函數(shù)。如果某個函數(shù)出現(xiàn)了異常,則其后所有的函數(shù)都不會執(zhí)行如果你的委托的委托鏈含有很多委托的話,你只會收到最后一個含有返回值的委托的返回值
      • 委托鏈?zhǔn)褂?=將方法鏈接。
    • System.Delegate是System.MulticastDelegate的父類,它含有2個非常重要的字段_target和_methodPtr。如果委托指向了一個實例方法,_target將會等于該實例本身。在方法中,可以通過this訪問。如果委托指向了一個靜態(tài)方法,_target將會等于null無論委托指向什么方法,_methodPtr都是CLR用于標(biāo)示委托指向方法的IntPtr值
    • 委托的構(gòu)造函數(shù)設(shè)置_invocationList,_target和_methodPtr在進行調(diào)用時,Invoke方法使用_target和_methodPtr在指定對象上調(diào)用對應(yīng)的方法
  • 事件

    • 事件必須包括三部分:
      • 事件的訂閱者(Subscriber),訂閱者會在事件觸發(fā)之后,做出響應(yīng)行為。
      • 事件的觸發(fā)者,或者發(fā)布者(Publisher),條件得到滿足時,觸發(fā)事件訂閱者和觸發(fā)者之間的數(shù)據(jù)傳送通道。
    • 事件使用步驟
      • 聲明一個事件處理方法,指出事件發(fā)生時,訂閱者應(yīng)該有怎樣的反應(yīng)。該方法可以傳入繼承自EventArgs類型的自定義數(shù)據(jù)
      • 聲明委托。委托的簽名和事件處理方法相同
      • 聲明基于該委托的事件
      • 為事件增加訂閱者
      • 在事件符合條件時,調(diào)用事件
    • 事件本身是私有的
      • 事件會被轉(zhuǎn)化為一個私有的字段,以及兩個方法。字段的類型和事件關(guān)聯(lián)的委托相同,而兩個方法的輸入類型和事件關(guān)聯(lián)的委托相同,沒有輸出
      • 事件將字段改為私有,從而令外部不能更改它的值
      • 在事件所處的對象之外,事件只能出現(xiàn)在+=,-=的左方
  • 泛型委托

    • C# 2 中提供了兩個泛型委托Action和Func
    • Action是沒有輸出的,F(xiàn)unc可以有一個輸出
    • 使用它們可以代替原始的delegate關(guān)鍵字

委托實際上就是函數(shù)指針,將不同函數(shù)像變量一樣傳遞,供不同參數(shù)調(diào)用。

匿名類型、var關(guān)鍵字和擴展方法

  • 隱式類型
    • 使用var關(guān)鍵字
    • 只能對局部變量使用隱式類型
    • 在foreach中一般不需要指定類型
  • 匿名類型
    • 匿名類型允許你直接在花括號內(nèi)建立類型,而無需指定類名稱
    • 只能用var或object來修飾,用var修飾可以用點來獲取成員
    • 如果兩個匿名類型有相同的成員,且成員類型相同,順序相同,編譯器會將它們做為同一個類型。
  • 擴展方法
    • 在不創(chuàng)建子類,不更改類型本身的情況下,修改類型
    • 擴展方法必須定義于靜態(tài)的類型中,且擴展方法必須是靜態(tài)的。
    • 擴展方法第一個輸入?yún)?shù)要加上this,擴展方法必須至少有一個輸入?yún)?shù)
//匿名類型
var s = new { name = "小李", age = 15 };
var b=s.name;
Console.WriteLine(s.GetType());//返回<>f__AnonymousType0`2[System.String,System.Int32]
//擴展方法
public static class StringExtension //1、在靜態(tài)類中,2、一般用Extension做為后綴
    {
        public static bool isHuiwen(this string input)
        {
            //算法
            return true;
        }
    }

bool a = "string".isHuiwen//調(diào)用

匿名方法和lambda表達式

  • 匿名方法出現(xiàn)在C#2中
  • 閉包:可以使用捕獲變量(在匿名方法外部的變量)
  • lambda表達式
    • C#3為了令代碼更加簡化,引入了lambda表達式
    • lambda表達式,是表達式的一種,它可以表式一個函數(shù)
    • 基本結(jié)構(gòu)分三個部分
      • 輸入?yún)?shù) 一個參數(shù)不需要括號,多個參數(shù)或沒有參數(shù)需要括號
      • 箭頭 =>
      • 表達式或語名塊 如有只一條件語句不需要花括號,多行需要花括號
//old:泛型委托實現(xiàn)字符串判定
static void Main(string[] args)
{
    var data = new List<string> { "string", "this", "the", "a", "dog" };
    var func = new Func<string, bool>(Predicate);//泛型委托實現(xiàn),string輸入的參數(shù),bool返回的類型
    
    //使用匿名方法的方式,不用在單獨定義Predicate這個方法
    var func1 = new Func<string, bool>(delegate (string input)
    {
        return input.Length >= 4;
    });
    //lamdbe表達式寫法
    Func<string, bool> func2 =(input)=>{
    return input.Length >= 4;
    };
    
    foreach (var word in data)
    {
        if (func(word))
        {
            Console.WriteLine(word);
        }
    }
    Console.ReadKey();
}
public static bool Predicate(string input)//使用匿名方法就這用寫這個了
{
    return input.Length >= 4;
}

LinQ Language-Integrated Query語言結(jié)構(gòu)化查詢

  • 工具準(zhǔn)備

    • linQpad
    • AdventureWork數(shù)據(jù)庫
  • LinQ查詢操作

    • LinQ分為查詢表達式和方法語法

    • 查詢表達式轉(zhuǎn)換為方法語法再轉(zhuǎn)化為SQL

      var data = Enumerable.Range(100, 20);
      //LinQ查詢(查詢表達式)
      var list1 = from s in data
                  where s > 115
                  select s;
      //LinQ查詢(方法語法)
      var list = data.Where(a => a > 115);
      Console.WriteLine(String.Join(",", list1));
      Console.ReadKey();
      
    • 投影操作符

      • Select 部分列(使用了匿名類型)
      • SelectMany 在“父子表”中,使用SelectMany進行查詢
    • 過濾操作符

      • Where 過濾
      • Distinct 會刪除序列中重復(fù)的元素
    • 排序操作符

      • OrderBy 升序
      • OrderByDescending 降序
      • ThenBy 多列排序,放在order后繼續(xù)排序
      • ThenByDescending 降序
    • 分組操作符

      • group by into
      from p in Persons
      group p by p.Name into g
      select new {name=p.key,count=g.count}
      
      var a=Persons.GroupBy(p=>p.Name)
               .Select(g=>new{
                 name=g.Key,
                 Count=g.Coutn()
               })
      
    • 連接操作符

      • 內(nèi)連接,左外連接和右外連接
      • 在進行內(nèi)連接時,必須要指明基于哪個列
       var customerList = new List<Customers>
              {
                  new Customers{ customerId=1,Name="張三",PhoneNumber=123,Address="中國" },
                  new Customers{ customerId=2,Name="李四",PhoneNumber=123,Address="中國" },
                  new Customers{ customerId=3,Name="王五",PhoneNumber=123,Address="中國" }
              };
              var infoList = new List<CustomerInfo>
              {
                  new CustomerInfo{ customerId=1, id=1,Number=70681  },
                  new CustomerInfo{ customerId=4, id=1,Number=70681  },
                  new CustomerInfo{ customerId=2, id=1,Number=70691  }
              };
              //連接基于兩個表,以及基于至少一列
              //左聯(lián)還是右聯(lián),基于哪個先寫
              var cus = from o in infoList
                        join c in customerList
                        //基于哪個列
                        on o.customerId equals c.customerId
                        select new { c.Name, o.Number };
              var cus1 = infoList.Join(customerList, 
                          o => o.customerId, 
                          c => c.customerId, 
                          (o, c) => new {
                              c.Name, c.Address, o.Number
                          });
              //左外連接,左邊的表中所有的數(shù)據(jù)都會出現(xiàn)在結(jié)果集中,右表要給默認(rèn)值
              var leftcus = from c in customerList 
                            join o in infoList
                            on c.customerId equals o.customerId into p
                            //右表默認(rèn)值
                            from item in p.DefaultIfEmpty(new CustomerInfo {  id = -1, Number=-1 })
                            select new { c.Name, c.Address, item.Number };
      
              Console.WriteLine(String.Join("\n", leftcus));
              Console.ReadKey();
      
    • 分區(qū)操作符

      • Take:從序列的開頭返回指定數(shù)量的連續(xù)元素,相當(dāng)于SQL的TOP N
      • Skip:跳過序列中指定數(shù)量的元素,然后返回剩余的元素
    • 集合操作符

      • 當(dāng)想操作兩個集合時非常有用。
      • Union:并集,返回兩個序列的并集,去掉重復(fù)元素,相當(dāng)于SQL的Union。
      • Concat:并集,返回兩個序列的并集,不處理重復(fù)元素,相當(dāng)于SQL的Union All。
      • Intersect:交集,返回兩個序列中都有的元素,即交集。
      • Except:差集,返回只出現(xiàn)在一個序列中的元素,即差集。
    • 元素操作符

      • First:返回序列中的第一個元素;如果是空序列,引發(fā)異常。
      • FirstOrDefault:返回序列中的第一個元素;如果是空,則返回默認(rèn)值default(TSource)。
      • Last:返回序列的最后一個元素;如果是空序列,此方法將引發(fā)異常。
      • LastOrDefault:返回序列中的最后一個元素;如果是空返回默認(rèn)值default(TSource)。
      • Single:返回序列的唯一元素;如果是空或多個元素,引發(fā)異常。該方法非常適合判斷序列是否只包含一個元素(并返回它)。
      • SingleOrDefault:返回序列中的唯一元素;如果是空,則返回默認(rèn)值default(TSource);如果該序列包含多個元素,此方法將引發(fā)異常。
  • 延遲執(zhí)行

    • 返回另外一個序列(通常為IEnumerable<T>或IQueryable<T>)的操作,會延遲執(zhí)行(在最終結(jié)果的第一個元素被訪問的時候才真正開始運算)
    • 返回單一值的運算,會立即執(zhí)行
    • 強制立即執(zhí)行,可以使用ToList()

反射和動態(tài)語言運行時

  • dynamic關(guān)鍵字
    • C#4引入動態(tài)類型dynamic,弱類型語言
    • dynamic與var的區(qū)域
      • 運行時推斷
      • var不能作為方法的輸入和返回值類型,dynamic可以
      • var不能修飾類或結(jié)構(gòu)的成員,dynamic可以
  • 反射
    • 在.net中,查看和操作元數(shù)據(jù)的動作稱為反射(Reflection)
    • 通過反射加載外部程序集/類型,并調(diào)用方法
    • 反射允許你訪問類型任何的成員,包括私有的
      //反射
      var type = typeof(ReflectionTest);
      //獲得類型所有的成員
      var members = type.GetMembers();
      //通過反射獲得構(gòu)造函數(shù)
      var constructor = type.GetConstructors()[0];
      //調(diào)用構(gòu)造函數(shù)
      object obj = constructor.Invoke(null);
      //通過反射調(diào)用實例方法,傳入實例
      var method = type.GetMethod("AddTwo");
      var o = method.Invoke(obj, new object[] { 100 });
      
      //動態(tài)語言運行時提供的晚期綁定方法
      //創(chuàng)建一個ReflectionTest類型的實例
      //讓它是一個動態(tài)類型
      dynamic dynamicObj = Activator.CreateInstance(typeof(ReflectionTest));
      //可以使用普通的方式調(diào)用方法
      //編譯器不檢查,不要拼錯
      var a = dynamicObj.AddTwo(100);
    
  • 動態(tài)類型簡化晚期綁定
    • 普通的反射
    • 動態(tài)類型使得方法呼叫更簡單
  • 動態(tài)類型簡化COM互操作
    • 我們可以使用C#創(chuàng)建并修改Word,Excel文件。這些都是基于COM
    • 沒有動態(tài)類型時,訪問COM對象必須使用類型強制轉(zhuǎn)換
    • 通過動態(tài)類型簡化代碼

C#5

C#2泛型
C#3LinQ
C#4動態(tài)語言運行時
C#5多線程

C#6-7

C#6-2015年7月,Vs2015 .net framework4.6語法糖
C#7-2017年3月,Vs2017 .net framework4.6.2增加元組和模式匹配,更具有函數(shù)式語言特性

  • 字符串插值
string name="張三";
string s="123";
//old
string.Format("{0}-{1}",name,s);
//new
$"{name}-{s}";
  • 使用static using呼叫靜態(tài)類方法
    • 為了降低代碼的冗余,我們希望在呼叫靜態(tài)類的方法時,可以省去類的名稱
  • 判斷null的簡寫操作符?.
    • 利用新的操作符“?.”(稱為nullet)可以簡化代碼
  • 異常過濾
    • 現(xiàn)在可以在catch后面跟when子句進一步對異常進行過濾并操作
    • 對于一些來自第三方傳回的帶有固定異常代碼的異常非常有用
  • [C# 7]改進的out關(guān)鍵字
    • 現(xiàn)在,out關(guān)鍵字是即插即用的
    • 允許以_(下劃線)形式“舍棄”某個out 參數(shù)
  • [C# 7]值類型元組(ValueTuple)
    • 元組(Tuple)是一個任意類型變量的集合,并最多支持八個變量
    • C# 4中元組最大的兩個問題是:
    • Tuple類將其屬性命名為 Item1、Item2等,這些名稱是無法改變的,因此只會讓代碼可讀性變差
    • Tuple類是引用類型,使用任一Tuple類型即意味著在堆上分配對象,因此,會對性能有負(fù)面影響,還不如辛苦一點手寫一個結(jié)構(gòu)體
    • C# 7引入的新元組(ValueTuple),解決了上面兩個問題,它是一個結(jié)構(gòu)體,并且,你可以傳入描述性名稱(TupleElementNames屬性)以便之后更容易的調(diào)用它們
    • 作為方法的參數(shù)和返回值,返回多個變量
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容