久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 转自:https://www.cnblogs.com/1996V/p/9037603.html#net1...

發布時間:2024/3/13 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 转自:https://www.cnblogs.com/1996V/p/9037603.html#net1... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?

什么是.NET?什么是.NET Framework?本文將從上往下,循序漸進的介紹一系列相關.NET的概念,先從類型系統開始講起,我將通過跨語言操作這個例子來逐漸引入一系列.NET的相關概念,這主要包括:CLS、CTS(CLI)、FCL、Windows下CLR的相關核心組成、Windows下托管程序運行概念、什么是.NET Framework,.NET Core,.NET Standard及一些VS編譯器相關雜項和相關閱讀鏈接。完整的從上讀到下則你可以理解個大概的.NET體系。

文章是我一字一字親手碼出來的,每天下班用休息時間寫一點,持續了二十來天。且對于文章上下銜接、概念引入花了很多心思,致力讓很多概念在本文中顯得通俗。但畢竟.NET系統很龐大,本文篇幅有限,所以在部分小節中我會給出延伸閱讀的鏈接,在文章結尾我給出了一些小的建議,希望能對需要幫助的人帶來幫助,如果想與我交流可以文章留言或者加.NET技術交流群:166843154

目錄

  • .NET和C#是什么關系
  • 跨語言和跨平臺是什么
  • 什么是跨語言互操作,什么是CLS
    • CLS異常
  • 什么是CTS?
  • 什么是類庫?
    • 什么是基礎類庫BCL?
    • 什么是框架類庫FCL?
  • 什么是基元類型?
  • System.Object的意義
  • 計算機是如何運行程序的?
    • 什么是CPU?
    • 什么是高級編程語言?
  • 什么是托管代碼,托管語言,托管模塊?
    • 非托管的異常
  • 什么是CLR,.NET虛擬機?
  • 什么是CLR宿主進程,運行時主機?
  • Windows系統自帶.NET Framework
  • .NET Framework 4.0.30319
    • .NET Framework4.X覆蓋更新
    • 如何確認本機安裝了哪些.NET Framework和對應CLR的版本?
  • 什么是程序集
  • 用csc.exe進行編譯
  • .NET程序執行原理
    • JIT編譯
    • AOT編譯
  • 程序集的規則
    • 程序集的加載方式
    • 強名稱程序集
    • 程序集搜索規則
    • 項目的依賴順序
    • 為什么Newtonsoft.Json版本不一致?
    • 如何在編譯時加載兩個相同的程序集
    • 如何同時調用兩個兩個相同命名空間和類型的程序集?
    • 共享程序集GAC
    • 延伸
  • 應用程序域
    • 跨邊界訪問
    • AppDomain和AppPool
  • 內存
    • 堆棧和堆的區別
    • 線程堆棧
    • 為什么值類型存儲在棧上
    • 托管堆模型
    • 選class還是struct
    • GC管理器
    • 弱引用、弱事件
    • GC堆回收
    • 垃圾回收對性能的影響
    • 性能建議
  • .NET程序執行圖
  • .NET的安全性
    • 基于角色的安全性
    • 代碼訪問安全性
  • 什么是.NET
    • 什么是.NET Framework
      • 如何在VS中調試.NET Framework源代碼
    • 什么是.NET Core
    • 什么是.NET Standard
    • .NET官方開源項目鏈接
  • Visual Studio
    • sln解決方案
    • 項目模板
    • csproj工程文件
    • 項目屬性雜項
    • IntelliTrace智能追溯
    • 鏈接
  • 建議

.NET和C#是什么關系

語言,是人們進行溝通表達的主要方式。編程語言,是人與機器溝通的表達方式。不同的編程語言,其側重點不同。有的編程語言是為了科學計算而開發的,所以其語法和功能更偏向于函數式思想。有些則是為了開發應用程序而創立的,所以其語法和功能更為均衡全面。

微軟公司是全球最大的電腦軟件提供商,為了占據開發者市場,進而在2002年推出了Visual Studio(簡稱VS,是微軟提供給開發者的工具集) .NET 1.0版本的開發者平臺。而為了吸引更多的開發者涌入平臺,微軟還在2002年宣布推出一個特性強大并且與.NET平臺無縫集成的編程語言,即C# 1.0正式版。 只要是.NET支持的編程語言,開發者就可以通過.NET平臺提供的工具服務和框架支持便捷的開發應用程序。

C#就是為宣傳.NET而創立的,它直接集成于Visual Studio .NET中,VB也在.NET 1.0發布后對其進行支持, 所以這兩門語言與.NET平臺耦合度很高,并且.NET上的技術大多都是以C#編程語言為示例,所以經常就.NET和C#混為一談(實質上它們是相輔相成的兩個概念)。 而作為一個開發者平臺,它不僅僅是包含開發環境、技術框架、社區論壇、服務支持等,它還強調了平臺的跨語言、跨平臺編程的兩個特性。

跨語言和跨平臺是什么

跨語言:即只要是面向.NET平臺的編程語言((C#、Visual Basic、C++/CLI、Eiffel、F#、IronPython、IronRuby、PowerBuilder、Visual COBOL 以及 Windows PowerShell)),用其中一種語言編寫的類型可以無縫地用在另一種語言編寫的應用程序中的互操作性。 跨平臺:一次編譯,不需要任何代碼修改,應用程序就可以運行在任意有.NET框架實現的平臺上,即代碼不依賴于操作系統,也不依賴硬件環境。

什么是跨語言互操作,什么是CLS

每門語言在最初被設計時都有其在功能和語法上的定位,讓不同的人使用擅長的語言去干合適的事,這在團隊協作時尤為重要。 .NET平臺上的跨語言是通過CLS這個概念來實現的,接下來我就以C#和VB來演示 什么是.NET中的跨語言互操作性。

通俗來說,雖然c#和vb是兩個不同的語言,但此處c#寫的類可以在vb中當做自家寫的類一樣正常使用。

比如我在vb中寫了一個針對String的首字母大寫的擴展方法,將其編譯后的dll引用至C#項目中。

在C#項目中,可以像自身代碼一樣正常使用來自vb這個dll的擴展方法。

現在有那么多面向對象語言,但不是所有編程語言都能這樣直接互操作使用,而.NET平臺支持的C#和VB之所以能這樣無縫銜接,先讀而后知,后文將會介紹緣由。不過雖然.NET平臺提供了這樣一個互操作的特性,但終究語言是不一樣的,每個語言有其特色和差異處,在相互操作的時候就會難免遇到一些例外情況。

比如我在C#中定義了一個基類,類里面包含一個公開的指針類型的成員,我想在vb中繼承這個類,并訪問這個公開的成員。

但是vb語言因為其定位不需要指針,所以并沒有C#中如int*這樣的指針類型,所以在vb中訪問一個該語言不支持的類型會報錯的,會提示:字段的類型不受支持。

再比如,C#語言中,對類名是區分大小寫的,我在C#中定義了兩個類,一個叫BaseBusiness,另一個叫baseBusiness。我在vb中去繼承這個BaseBusiness類。

如圖,在vb中訪問這個類會報錯的,報:"BaseBusiness"不明確,這是因為在vb中對類名是不區分大小寫的。在vb中,它認為它同時訪問了兩個一模一樣的類,所以按照vb的規則這是不合理的。那么為了在vb調用c#的程序集中避免這些因語言的差異性而導致的錯誤,在編寫c#代碼的時候 就應該提前知道vb中的這些規則,來應付式的開發。?

但是,如果我想不僅僅局限于C#和VB,我還想我編寫的代碼在.Net平臺上通用的話,那么我還必須得知道.NET平臺支持的每一種語言和我編寫代碼所使用的語言的差異,從而在編寫代碼中避免這些。

這幾年編程語言層出不窮,在將來.NET可能還會支持更多的語言,如果說對一個開發者而言掌握所有語言的差異處這是不現實的,所以.NET專門為此參考每種語言并找出了語言間的共性,然后定義了一組規則,開發者都遵守這個規則來編碼,那么代碼就能被任意.NET平臺支持的語言所通用。 而與其說是規則,不如說它是一組語言互操作的標準規范,它就是公共語言規范 - Common Language Specification ,簡稱CLS

?CLS從類型、命名、事件、屬性、數組等方面對語言進行了共性的定義及規范。這些東西被提交給歐洲計算機制造聯合會ECMA,稱為:共同語言基礎設施。

就以類型而言,CLS定義了在C#語言中符合規范的類型和不符合的有:

當然,就編碼角度而言,我們不是必須要看那些詳略的文檔。為了方便開發者開發,.NET提供了一個特性,名叫:CLSCompliantAttribute,代碼被CLSCompliantAttribute標記后,如果你寫的代碼不符合CLS規范的話,編譯器就會給你一條警告。

?

值得一提的是,CLS規則只是面向那些公開可被其它程序集訪問的成員,如public、繼承的protected,對于該程序集的內部成員如Private、internal則不會執行該檢測規則。也就是說,所適應的CLS遵從性規則,僅是那些公開的成員,而非私有實現。

那么有沒有那種特殊情況,比如我通過反射技術來訪問該程序集中,當前語言并不擁有的類型時會發生什么情況呢?

答案是可以嘗試的,如用vb反射訪問c#中的char*指針類型,即使vb中沒有char*這種等價的指針類型,但mscorlib提供了針對指針類型的 Pointer 包裝類供其訪問,可以從運行時類攜帶的類型名稱看到其原本的類型名。

可以看到,該類中的元素是不符合CLS規范的。

CLS異常

提到特殊情況,還要說的一點就是異常處理。.NET框架組成中定義了異常類型系統,在編譯器角度,所有catch捕獲的異常都必須繼承自System.Exception,如果你要調用一個 由不遵循此規范的語言 拋出其它類型的異常對象(C++允許拋出任何類型的異常,如C#調用C++代碼,C++拋出一個string類型的異常),在C#2.0之前Catch(Exception)是捕捉不了的,但之后的版本可以。 在后續版本中,微軟提供了System.Runtime.CompilerServices.RuntimeWrappedException異常類,將那些不符合CLS的包含Exception的對象封裝起來。并且可以通過RuntimeCompatibilityAttribute特性來過濾這些異常。 RuntimeWrappedException :https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.compilerservices.runtimewrappedexception?view=netframework-4.7.2

那么,這個段落總結一下,什么是CLS呢?

在面向.NET開發中,編寫跨語言組件時所遵循的那些共性,那些規范就叫做 Common Langrage Specification簡稱 CLS,公共語言規范? 官方CLS介紹:https://docs.microsoft.com/zh-cn/dotnet/standard/language-independence-and-language-independent-components

什么是CTS?

如果理解了什么是CLS的話,那么你將很輕松理解什么是CTS。 假設你已經圍繞著封裝 繼承 多態 這3個特性設計出了多款面向對象的語言,你發現大家都是面向對象,都能很好的將現實中的對象模型表達出來。除了語法和功能擅長不同,語言的定義和設計結構其實都差不多一回事。

比如,現實中你看到了一輛小汽車,這輛車里坐著兩個人,那么如何用這門語言來表達這樣的一個概念和場面? 首先要為這門語言橫向定義一個“類型”的概念。接下來在程序中就可以這樣表示:有一個汽車類型,有一個人類型,在一個汽車類型的對象內包含著兩個人類型的對象,因為要表達出這個模型,你又引入了“對象”的概念 。而現在,你又看到,汽車里面的人做出了開車的這樣一個動作,由此你又引入了“動作指令”這樣一個概念。 接著,你又恍然大悟總結出一個定理,無論是什么樣的“類型”,都只會存在這樣一個特征,即活著的 帶生命特征的(如人) 和 死的 沒有生命特征的(如汽車) 這兩者中的一個。最后,隨著思想模型的成熟,你發現,這個“類型”就相當于一個富有主體特征的一組指令的集合。 好,然后你開始照葫蘆畫瓢。你參考其它程序語言,你發現大家都是用class來表示類的含義,用struct表示結構的含義,用new來表示 新建一個對象的含義,于是,你對這部分功能的語法也使用class和new關鍵字來表示。然后你又發現,他們還用很多關鍵字來更豐富的表示這些現實模型,比如override、virtual等。于是,在不斷的思想升級和借鑒后,你對這個設計語言過程中思想的變化仔細分析,對這套語言體系給抽象歸納,最終總結出一套體系。

于是你對其它人這樣說,我總結出了一門語言很多必要的東西如兩種主要類別:值類別和引用類別,五個主要類型:類、接口、委托、結構、枚舉,我還規定了,一個類型可以包含字段、屬性、方法、事件等成員,我還指定了每種類型的可見性規則和類型成員的訪問規則,等等等等,只要按照我這個體系來設計語言,設計出來的語言它能夠擁有很多不錯的特性,比如跨語言,跨平臺等,C#和VB.net之所以能夠這樣就是因為這兩門語言的設計符合我這個體系。

那么,什么是CTS呢?

當你需要設計面向.Net的語言時所需要遵循一個體系(.Net平臺下的語言都支持的一個體系)這個體系就是CTS(Common Type System 公共類型系統),它包括但不限于:

  • 建立用于跨語言執行的框架。
  • 提供面向對象的模型,支持在 .NET 實現上實現各種語言。
  • 定義處理類型時所有語言都必須遵守的一組規則(CLS)。
  • 提供包含應用程序開發中使用的基本基元數據類型(如 Boolean、Byte、Char 等)的庫。

上文的CLS是CTS(Common Type System 公共類型系統)這個體系中的子集。 一個編程語言,如果它能夠支持CTS,那么我們就稱它為面向.NET平臺的語言。 官方CTS介紹:?https://docs.microsoft.com/zh-cn/dotnet/standard/common-type-system?

微軟已經將CTS和.NET的一些其它組件,提交給ECMA以成為公開的標準,最后形成的標準稱為CLI(Common Language Infrastructure)公共語言基礎結構。 所以有的時候你見到的書籍或文章有的只提起CTS,有的只提起CLI,請不要奇怪,你可以寬泛的把他們理解成一個意思,CLI是微軟將CTS等內容提交給國際組織計算機制造聯合會ECMA的一個工業標準。

什么是類庫?

在CTS中有一條就是要求基元數據類型的類庫。我們先搞清什么是類庫?類庫就是類的邏輯集合,你開發工作中你用過或自己編寫過很多工具類,比如搞Web的經常要用到的 JsonHelper、XmlHelper、HttpHelper等等,這些類通常都會在命名為Tool、Utility等這樣的項目中。 像這些類的集合我們可以在邏輯上稱之為 "類庫",比如這些Helper我們統稱為工具類庫。

什么是基礎類庫BCL?

當你通過VS創建一個項目后,你這個項目就已經引用好了通過.NET下的語言編寫好的一些類庫。比如控制臺中你直接就可以用ConSole類來輸出信息,或者using System.IO 即可通過File類對文件進行讀取或寫入操作,這些類都是微軟幫你寫好的,不用你自己去編寫,它幫你編寫了一個面向.NET的開發語言中使用的基本的功能,這部分類,我們稱之為BCL(Base Class Library), 基礎類庫,它們大多都包含在System命名空間下。

基礎類庫BCL包含:基本數據類型,文件操作,集合,自定義屬性,格式設置,安全屬性,I/O流,字符串操作,事件日志等的類型

什么是框架類庫FCL?

有關BCL的就不在此一一類舉。.NET之大,發展至今,由微軟幫助開發人員編寫的類庫越來越多,這讓我們開發人員開發更加容易。由微軟開發的類庫統稱為:FCL,Framework Class Library ,.NET框架類庫,我上述所表達的BCL就是FCL中的一個基礎部分,FCL中大部分類都是通過C#來編寫的。

在FCL中,除了最基礎的那部分BCL之外,還包含我們常見的 如 : 用于網站開發技術的 ASP.NET類庫,該子類包含webform/webpage/mvc,用于桌面開發的 WPF類庫、WinForm類庫,用于通信交互的WCF、asp.net web api、Web Service類庫等等

什么是基元類型?

像上文在CTS中提到了 基本基元數據類型,大家知道,每門語言都會定義一些基礎的類型,比如C#通過 int 來定義整型,用 string 來定義 字符串 ,用 object 來定義 根類。當我們來描述這樣一個類型的對象時可以有這兩種寫法,如圖:

我們可以看到,上邊用首字母小寫的藍色體string、object能描述,用首字母大寫的淺藍色String、Object也能描述,這兩種表述方式有何不同?

要知道,在vs默認的顏色方案中,藍色體 代表關鍵字,淺藍色體 代表類型。 那么這樣也就意味著,由微軟提供的FCL類庫里面 包含了 一些用于描述數據類型的 基礎類型,無論我們使用的是什么語言,只要引用了FCL,我們都可以通過new一個類的方式來表達數據類型。 如圖:

用new來創建這些類型的對象,但這樣就太繁瑣,所以C#就用 int關鍵字來表示System.Int32,用 string關鍵字來表示 System.String等,所以我們才能這樣去寫。

像這樣被表述于編譯器直接支持的類型叫做基元類型,它被直接映射于BCL中具體的類。

下面是部分面向.NET的語言的基元類型與對應的BCL的類別圖 :

System.Object的意義

說起類型,這里要說CTS定義的一個非常重要的規則,就是類與類之間只能單繼承,System.Object類是所有類型的根,任何類都是顯式或隱式的繼承于System.Object。

??? System.Object定義了類型的最基本的行為:用于實例比較的Equals系列方法、用于Hash表中Hash碼的GetHashCode、用于Clr運行時獲取的類型信息GetType、用于表示當前對象字符串的ToString、用于執行實例的淺復制MemberwiseClone、用于GC回收前操作的析構方法Finalize 這6類方法。

所以 Object不僅是C#語言的類型根、還是VB等所有面向.NET的語言的類型根,它是整個FCL的類型根。

???當然,CTS定義了單繼承,很多編程語言都滿足這個規則,但也有語言是例外,如C++就不做繼承限制,可以繼承多個,C++/CLI作為C++在對.NET的CLI實現,如果在非托管編碼中多繼承那也可以,如果試圖在托管代碼中多繼承,那就會報錯。我前面已經舉過這樣特殊情況的例子,這也在另一方面反映出,各語言對CTS的支持并不是都如C#那樣全面的,我們只需明記一點:對于符合CTS的那部分自然就按照CTS定義的規則來。 任何可遵循CTS的類型規范,同時又有.NET運行時的實現的編程語言就可以成為.NET中的一員。

計算機是如何運行程序的?

接下來我要說什么是.NET的跨平臺,并解釋為什么能夠跨語言。不過要想知道什么是跨平臺,首先你得知道一個程序是如何在本機上運行的。

什么是CPU

CPU,全稱Central Processing Unit,叫做中央處理器,它是一塊超大規模的集成電路,是計算機組成上必不可少的組成硬件,沒了它,計算機就是個殼。 無論你編程水平怎樣,你都應該先知道,CPU是一臺計算機的運算核心和控制核心,CPU從存儲器或高速緩沖存儲器中取出指令,放入指令寄存器,并對指令譯碼,執行指令。 我們運行一個程序,CPU就會不斷的讀取程序中的指令并執行,直到關閉程序。事實上,從電腦開機開始,CPU就一直在不斷的執行指令直到電腦關機。

什么是高級編程語言

在計算機角度,每一種CPU類型都有自己可以識別的一套指令集,計算機不管你這個程序是用什么語言來編寫的,其最終只認其CPU能夠識別的二進制指令集。 在早期計算機剛發展的時代,人們都是直接輸入01010101這樣的沒有語義的二進制指令來讓計算機工作的,可讀性幾乎沒有,沒人愿意直接編寫那些沒有可讀性、繁瑣、費時,易出差錯的二進制01代碼,所以后來才出現了編程語言。

編程語言的誕生,使得人們編寫的代碼有了可讀性,有了語義,與直接用01相比,更有利于記憶。 而前面說了,計算機最終只識別二進制的指令,那么,我們用編程語言編寫出來的代碼就必須要轉換成供機器識別的指令。 就像這樣:

code: 1+2 function 翻譯方法(參數:code) { ... "1"=>"001"; "2"=>"002"; "+"=>"000"; return 能讓機器識別的二進制代碼; } call 翻譯方法("1+2") => "001 000 002"

所以從一門編程語言所編寫的代碼文件轉換成能讓本機識別的指令,這中間是需要一個翻譯的過程。 而我們現在計算機上是運載著操作系統的,光翻譯成機器指令也不行,還得讓代碼文件轉化成可供操作系統執行的程序才行。 那么這些步驟,就是編程語言所對應的編譯環節的工程了。這個翻譯過程是需要工具來完成,我們把它叫做 編譯器。

不同廠商的CPU有著不同的指令集,為了克服面向CPU的指令集的難讀、難編、難記和易出錯的缺點,后來就出現了面向特定CPU的特定匯編語言, 比如我打上這樣的x86匯編指令 mov ax,bx ,然后用上用機器碼做的匯編器,它將會被翻譯成 1000100111011000 這樣的二進制01格式的機器指令.

不同CPU架構上的匯編語言指令不同,而為了統一一套寫法,同時又不失匯編的表達能力,C語言就誕生了。 用C語言寫的代碼文件,會被C編譯器先轉換成對應平臺的匯編指令,再轉成機器碼,最后將這些過程中產生的中間模塊鏈接成一個可以被操作系統執行的程序。

那么匯編語言和C語言比較,我們就不需要去閱讀特定CPU的匯編碼,我只需要寫通用的C源碼就可以實現程序的編寫,我們用將更偏機器實現的匯編語言稱為低級語言,與匯編相比,C語言就稱之為高級語言。

在看看我們C#,我們在編碼的時候都不需要過于偏向特定平臺的實現,翻譯過程也基本遵循這個過程。它的編譯模型和C語言類似,都是屬于這種間接轉換的中間步驟,故而能夠跨平臺。 所以就類似于C/C#等這樣的高級語言來說是不區分平臺的,而在于其背后支持的這個 翻譯原理 是否能支持其它平臺。

什么是托管代碼,托管語言,托管模塊?

作為一門年輕的語言,C#借鑒了許多語言的長處,與C比較,C#則更為高級。 往往一段簡小的C#代碼,其功能卻相當于C的一大段代碼,并且用C#語言你幾乎不需要指針的使用,這也就意味著你幾乎不需要進行人為的內存管控與安全考慮因素,也不需要多懂一些操作系統的知識,這讓編寫程序變得更加輕松和快捷。

如果說C#一段代碼可以完成其它低級語言一大段任務,那么我們可以說它特性豐富或者類庫豐富。而用C#編程不需要人為內存管控是怎么做到的呢? ??? .NET提供了一個垃圾回收器(GC)來完成這部分工作,當你創建類型的時候,它會自動給你分配所需要的這部分內存空間。就相當于,有一個專門的軟件或進程,它會讀取你的代碼,然后當你執行這行代碼的時候,它幫你做了內存分配工作。 這部分本該你做的工作,它幫你做了,這就是“托管”的概念。比如現實中 托管店鋪、托管教育等這樣的別人替你完成的概念。

因此,C#被稱之為托管語言。C#編寫的代碼也就稱之為托管代碼,C#生成的模塊稱之為托管模塊等。(對于托管的資源,是不需要也無法我們人工去干預的,但我們可以了解它的一些機制原理,在后文我會簡單介紹。)

只要有比較,就會產生概念。那么在C#角度,那些脫離了.NET提供的諸如垃圾回收器這樣的環境管制,就是對應的 非托管了。

非托管的異常

我們編寫的程序有的模塊是由托管代碼編寫,有的模塊則調用了非托管代碼。在.NET Framework中也有一套基于此操作系統SEH的異常機制,理想的機制設定下我們可以直接通過catch(e)或catch來捕獲指定的異常和框架設計人員允許我們捕獲的異常。

而異常類型的級別也有大有小,有小到可以直接框架本身或用代碼處理的,有大到需要操作系統的異常機制來處理。.NET會對那些能讓程序崩潰的異常類型給進行標記,對于這部分異常,在.NET Framework 4.0之前允許開發人員在代碼中自己去處理,但4.0版本之后有所變更,這些被標記的異常默認不會在托管環境中拋出(即無法catch到),而是由操作系統的SEH機制去處理。? 不過如果你仍然想在代碼中捕獲處理這樣的異常也是可以的,你可以對需要捕獲的方法上標記[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute]特性,就可以在該方法內通過catch捕獲到該類型的異常。你也可以通過在配置文件中添加運行時節點來對全局進行這樣的一個配置:

<runtime><legacyCorruptedStateExceptionsPolicy enabled="true" /> </runtime>

HandleProcessCorruptedStateExceptions特性:https://msdn.microsoft.com/zh-cn/library/azure/system.runtime.exceptionservices.handleprocesscorruptedstateexceptionsattribute.aspx? SEHException類:https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.sehexception(v=vs.100).aspx? 處理損壞狀態異常博客專欄:?https://msdn.microsoft.com/zh-cn/magazine/dd419661.aspx

什么是CLR,.NET虛擬機?

實際上,.NET不僅提供了自動內存管理的支持,他還提供了一些列的如類型安全、應用程序域、異常機制等支持,這些 都被統稱為CLR公共語言運行庫。

CLR是.NET類型系統的基礎,所有的.NET技術都是建立在此之上,熟悉它可以幫助我們更好的理解框架組件的核心、原理。 在我們執行托管代碼之前,總會先運行這些運行庫代碼,通過運行庫的代碼調用,從而構成了一個用來支持托管程序的運行環境,進而完成諸如不需要開發人員手動管理內存,一套代碼即可在各大平臺跑的這樣的操作。

這套環境及體系之完善,以至于就像一個小型的系統一樣,所以通常形象的稱CLR為".NET虛擬機"。那么,如果以進程為最低端,進程的上面就是.NET虛擬機(CLR),而虛擬機的上面才是我們的托管代碼。換句話說,托管程序實際上是寄宿于.NET虛擬機中。

什么是CLR宿主進程,運行時主機?

那么相對應的,容納.NET虛擬機的進程就是CLR宿主進程了,該程序稱之為運行時主機。

這些運行庫的代碼,全是由C/C++編寫,具體表現為以mscoree.dll為代表的核心dll文件,該dll提供了N多函數用來構建一個CLR環境 ,最后當運行時環境構建完畢(一些函數執行完畢)后,調用_CorDllMain或_CorExeMain來查找并執行托管程序的入口方法(如控制臺就是Main方法)。

如果你足夠熟悉CLR,那么你完全可以在一個非托管程序中通過調用運行庫函數來定制CLR并執行托管代碼。 像SqlServer就集成了CLR,可以使用任何 .NET Framework 語言編寫存儲過程、觸發器、用戶定義類型、用戶定義函數(標量函數和表值函數)以及用戶定義的聚合函數。

有關CLR大綱介紹:?https://msdn.microsoft.com/zh-cn/library/9x0wh2z3(v=vs.85).aspx? CLR集成:?https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/ms131052(v%3dsql.100)? 構造CLR的接口:https://msdn.microsoft.com/zh-cn/library/ms231039(v=vs.85).aspx? 適用于 .NET Framework 2.0 的宿主接口:https://msdn.microsoft.com/zh-cn/library/ms164336(v=vs.85).aspx 選擇CLR版本:?https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element

所以C#編寫的程序如果想運行就必須要依靠.NET提供的CLR環境來支持。 而CLR是.NET技術框架中的一部分,故只要在Windows系統中安裝.NET Framework即可。

Windows系統自帶.NET Framework

Windows系統默認安裝的有.NET Framework,并且可以安裝多個.NET Framework版本,你也不需要因此卸載,因為你使用的應用程序可能依賴于特定版本,如果你移除該版本,則應用程序可能會中斷。

Microsoft .NET Framework百度百科下有windows系統默認安裝的.NET版本?

圖出自?https://baike.baidu.com/item/Microsoft%20.NET%20Framework/9926417?fr=aladdin

.NET Framework 4.0.30319

在%SystemRoot%\Microsoft.NET下的Framework和Framework64文件夾中分別可以看到32位和64位的.NET Framework安裝的版本。 我們點進去可以看到以.NET版本號為命名的文件夾,有2.0,3.0,3.5,4.0這幾個文件夾。

?

.NET Framework4.X覆蓋更新

要知道.NET Framework版本目前已經迭代到4.7系列,電腦上明明安裝了比4.0更高版本的.NET Framework,然而從文件夾上來看,最高不過4.0,這是為何? ??? 原來自.NET Framework 4以來的所有.NET Framework版本都是直接在v4.0.30319文件夾上覆蓋更新,并且無法安裝以前的4.x系列的老版本,所以v4.0.30319這個目錄中其實放的是你最后一次更新的NET Framework版本。 .NET Framework覆蓋更新:https://docs.microsoft.com/en-us/dotnet/framework/install/guide-for-developers

如何確認本機安裝了哪些.NET Framework和對應CLR的版本?

我們可以通過注冊表等其它方式來查看安裝的最新版本:https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed?。 不過如果不想那么復雜的話,還有種最直接簡單的: 那就是進入該目錄文件夾,隨便找到幾個文件對其右鍵,然后點擊詳細信息即可查看到對應的文件版本,可以依據文件版本估摸出.NET Framework版本,比如csc.exe文件。

?

什么是程序集

上文我介紹了編譯器,即將源代碼文件給翻譯成一個計算機可識別的二進制程序。而在.NET Framework目錄文件夾中就附帶的有 用于C#語言的命令行形式的編譯器csc.exe 和 用于VB語言的命令行形式的編譯器vbc.exe。

我們通過編譯器可以將后綴為.cs(C#)和.vb(VB)類型的文件編譯成程序集。 程序集是一個抽象的概念,不同的編譯選項會產生不同形式的程序集。以文件個數來區分的話,那么就分 單文件程序集(即一個文件)和多文件程序集(多個文件)。 而不論是單文件程序集還是多文件程序集,其總有一個核心文件,就是表現為后綴為.dll或.exe格式的文件。它們都是標準的PE格式的文件,主要由4部分構成:

  • 1.PE頭,即Windows系統上的可移植可執行文件的標準格式
  • 2.CLR頭,它是托管模塊特有的,它主要包括
    • 1)程序入口方法
    • 2)CLR版本號等一些標志
    • 3)一個可選的強名稱數字簽名
    • 4)元數據表,主要用來記錄了在源代碼中定義和引用的所有的類型成員(如方法、字段、屬性、參數、事件...)的位置和其標志Flag(各種修飾符)? ??????正是因為元數據表的存在,VS才能智能提示,反射才能獲取MemberInfo,CLR掃描元數據表即可獲得該程序集的相關重要信息,所以元數據表使得程序集擁有了自我描述的這一特性。clr2中,元數據表大概40多個,其核心按照用途分為3類:
      • 1.即用于記錄在源代碼中所定義的類型的定義表:ModuleDef、TypeDef、MethodDef、ParamDef、FieldDef、PropertyDef、EventDef,
      • 2.引用了其它程序集中的類型成員的引用表:MemberRef、AssemblyRef、ModuleRef、TypeRef
      • 3. 用于描述一些雜項(如版本、發布者、語言文化、多文件程序集中的一些資源文件等)的清單表:AssemblyDef、FileDef、ManifestResourceDef、ExportedTypeDef
  • 3.IL代碼(也稱MSIL,后來被改名為CIL:Common Intermediate Language通用中間語言),是介于源代碼和本機機器指令中間的代碼,將通過CLR在不同的平臺產生不同的二進制機器碼。
  • 4.一些資源文件

多文件程序集的誕生場景有:比如我想為.exe綁定資源文件(如Icon圖標),或者我想按照功能以增量的方式來按需編譯成.dll文件。 通常很少情況下才會將源代碼編譯成多文件程序集,并且在VS IDE中總是將源代碼給編譯成單文件的程序集(要么是.dll或.exe),所以接下來我就以單文件程序集為例來講解。

用csc.exe進行編譯

現在,我將演示一段文本是如何被csc.exe編譯成一個可執行的控制臺程序的。 我們新建個記事本,然后將下面代碼復制上去。

View Code

然后關閉記事本,將之.txt的后綴改為.cs的后綴(后綴是用來標示這個文件是什么類型的文件,并不影響文件的內容)。

上述代碼相當于Web中的http.sys偽實現,是建立了通信的socket服務端,并通過while循環來不斷的監視獲取包的數據實現最基本的監聽功能,最終我們將通過csc.exe將該文本文件編譯成一個控制臺程序。

我已經在前面講過BCL,基礎類庫。在這部分代碼中,為了完成我想要的功能,我用到了微軟已經幫我們實現好了的String數據類型系列類(.NET下的一些數據類型)、Environment類(提供有關當前環境和平臺的信息以及操作它們的方法)、Console類(用于控制臺輸入輸出等)、Socket系列類(對tcp協議抽象的接口)、File文件系列類(對文件目錄等操作系統資源的一些操作)、Encoding類(字符流的編碼)等 這些類,都屬于BCL中的一部分,它們存在但不限于mscorlib.dll、System.dll、System.core.dll、System.Data.dll等這些程序集中。 附:不要糾結BCL到底存在于哪些dll中,總之,它是個物理分散,邏輯上的類庫總稱。

mscorlib.dll和System.dll的區別:https://stackoverflow.com/questions/402582/mscorlib-dll-system-dll

因為我用了這些類,那么按照編程規則我必須在代碼中using這些類的命名空間,并通過csc.exe中的 /r:dll路徑 命令來為生成的程序集注冊元數據表(即以AssemblyRef為代表的程序集引用表)。 而這些代碼引用了4個命名空間,但實際上它們只被包含在mscorlib.dll和System.dll中,那么我只需要在編譯的時候注冊這兩個dll的信息就行了。

好,接下來我將通過cmd運行csc.exe編譯器,再輸入編譯命令: csc /out:D:\demo.exe D:\dic\demo.cs /r:D:\dic\System.dll

/r:是將引用dll中的類型數據注冊到程序集中的元數據表中 。 /out:是輸出文件的意思,如果沒有該命令則默認輸出{name}.exe。? 使用csc.exe編譯生成:?https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe? csc編譯命令行介紹:https://www.cnblogs.com/shuang121/archive/2012/12/24/2830874.html

總之,你除了要掌握基本的編譯指令外,當你打上這行命令并按回車后,必須滿足幾個條件,1.是.cs后綴的c#格式文件,2.是 代碼語法等檢測分析必須正確,3.是 使用的類庫必須有出處(引用的dll),當然 因為我是編譯為控制臺程序,所以還必須得有個靜態Main方法入口,以上缺一不可。

可以看出,這段命令我是將 位于D:\dic\的demo.cs文件給編譯成 位于D:\名為demo.exe的控制臺文件,并且因為在代碼中使用到了System.dll,所以還需要通過/r注冊該元數據表。 這里得注意為什么沒有/r:mscorlib.dll,因為mscorlib.dll地位的特殊,所以csc總是對每個程序集進行mscorlib.dll的注冊(自包含引用該dll),因此我們可以不用/r:mscorlib.dll這個引用命令,但為了演示效果我還是決定通過/nostdlib命令來禁止csc默認導入mscorlib.dll文件。

所以,最終命令是這樣的: csc D:\dic\demo.cs /r:D:\dic\mscorlib.dll /r:D:\dic\System.dll /nostdlib

因為沒有指定輸出文件/out選項, 所以會默認輸出在與csc同一目錄下名為demo.exe的文件。事實上,在csc的命令中,如果你沒有指定路徑,那么就默認采用在csc.exe的所在目錄的相對路徑。

而我們可以看到,在該目錄下有許多程序集,其中就包含我們需要的System.dll和mscorlib.dll,所以我們完全可以直接/r:mscorlib.dll /r:System.dll

而類似于System.dll、System.Data.dll這樣使用非常頻繁的程序集,我們其實不用每次編譯的時候都去手動/r一下,對于需要重復勞動的編譯指令,我們可以將其放在后綴為.rsp的指令文件中,然后在編譯時直接調用文件即可執行里面的命令 @ {name}.rsp。

csc.exe默認包含csc.rsp文件,我們可以用/noconfig來禁止默認包含,而csc.rsp里面已經寫好了我們會經常用到的指令。 所以,最終我可以這樣寫 csc D:\dic\demo.cs 直接生成控制臺應用程序。

.NET程序執行原理

好的,現在我們已經有了一個demo.exe的可執行程序,它是如何被我們運行的?。

C#源碼被編譯成程序集,程序集內主要是由一些元數據表和IL代碼構成,我們雙擊執行該exe,Windows加載器將該exe(PE格式文件)給映射到虛擬內存中,程序集的相關信息都會被加載至內存中,并查看PE文件的入口點(EntryPoint)并跳轉至指定的mscoree.dll中的_CorExeMain函數,該函數會執行一系列相關dll來構造CLR環境,當CLR預熱后調用該程序集的入口方法Main(),接下來由CLR來執行托管代碼(IL代碼)。

JIT編譯

前面說了,計算機最終只識別二進制的機器碼,在CLR下有一個用來將IL代碼轉換成機器碼的引擎,稱為Just In Time Compiler,簡稱JIT,CLR總是先將IL代碼按需通過該引擎編譯成機器指令再讓CPU執行,在這期間CLR會驗證代碼和元數據是否類型安全(在對象上只調用正確定義的操作、標識與聲稱的要求一致、對類型的引用嚴格符合所引用的類型),被編譯過的代碼無需JIT再次編譯,而被編譯好的機器指令是被存在內存當中,當程序關閉后再打開仍要重新JIT編譯。

AOT編譯

CLR的內嵌編譯器是即時性的,這樣的一個很明顯的好處就是可以根據當時本機情況生成更有利于本機的優化代碼,但同樣的,每次在對代碼編譯時都需要一個預熱的操作,它需要一個運行時環境來支持,這之間還是有消耗的。

而與即時編譯所對應的,就是提前編譯了,英文為Ahead of Time Compilation,簡稱AOT,也稱之為靜態編譯。 在.NET中,使用Ngen.exe或者開源的.NET Native可以提前將代碼編譯成本機指令。

Ngen是將IL代碼提前給全部編譯成本機代碼并安裝在本機的本機映像緩存中,故而可以減少程序因JIT預熱的時間,但同樣的也會有很多注意事項,比如因JIT的喪失而帶來的一些特性就沒有了,如類型驗證。Ngen僅是盡可能代碼提前編譯,程序的運行仍需要完整的CLR來支持。
.NET Native在將IL轉換為本機代碼的時候,會嘗試消除所有元數據將依靠反射和元數據的代碼替換為靜態本機代碼,并且將完整的CLR替換為主要包含垃圾回收器的重構運行時mrt100_app.dll。

.NET Native:?https://docs.microsoft.com/zh-cn/dotnet/framework/net-native/? Ngen.exe:https://docs.microsoft.com/zh-cn/dotnet/framework/tools/ngen-exe-native-image-generator? Ngen與.NET Native比較:https://www.zhihu.com/question/27997478/answer/38978762

---------------------------------------------------

現在,我們可以通過ILDASM工具(一款查看程序集IL代碼的軟件,在Microsoft SDKs目錄中的子目錄中)來查看該程序集的元數據表和Main方法中間碼。

c#源碼第一行代碼:string rootDirectory = Environment.CurrentDirectory;被翻譯成IL代碼: call string [mscorlib/*23000001*/]System.Environment/*01000004*/::get_CurrentDirectory() /* 0A000003 */?

這句話意思是調用 System.Environment類的get_CurrentDirectory()方法(屬性會被編譯為一個私有字段+對應get/set方法)。

點擊視圖=>元信息=>顯示,即可查看該程序集的元數據。 我們可以看到System.Environment標記值為01000004,在TypeRef類型引用表中找到該項:

注意圖,TypeRefName下面有該類型中被引用的成員,其標記值為0A000003,也就是get_CurrentDirectory了。 而從其ResolutionScope指向位于0x23000001而得之,該類型存在于mscorlib程序集。

于是我們打開mscorlib.dll的元數據清單,可以在類型定義表(TypeDef)找到System.Environment,可以從元數據得知該類型的一些標志(Flags,常見的public、sealed、class、abstract),也得知繼承(Extends)于System.Object。在該類型定義下還有類型的相關信息,我們可以在其中找到get_CurrentDirectory方法。 我們可以得到該方法的相關信息,這其中表明了該方法位于0x0002b784這個相對虛地址(RVA),接著JIT在新地址處理CIL,周而復始。

元數據在運行時的作用:?https://docs.microsoft.com/zh-cn/dotnet/standard/metadata-and-self-describing-components#run-time-use-of-metadata

程序集的規則

上文我通過ILDASM來描述CLR執行代碼的方式,但還不夠具體,還需要補充的是對于程序集的搜索方式。

對于System.Environment類型,它存在于mscorlib.dll程序集中,demo.exe是個獨立的個體,它通過csc編譯的時候只是注冊了引用mscorlib.dll中的類型的引用信息,并沒有記錄mscorlib.dll在磁盤上的位置,那么,CLR怎么知道get_CurrentDirectory的代碼?它是從何處讀取mscorlib.dll的?? 對于這個問題,.NET有個專門的概念定義,我們稱為 程序集的加載方式。

程序集的加載方式

對于自身程序集內定義的類型,我們可以直接從自身程序集中的元數據中獲取,對于在其它程序集中定義的類型,CLR會通過一組規則來在磁盤中找到該程序集并加載在內存。

CLR在查找引用的程序集的位置時候,第一個判斷條件是 判斷該程序集是否被簽名。 什么是簽名?

強名稱程序集

就比如大家都叫張三,姓名都一樣,喊一聲張三不知道到底在叫誰。這時候我們就必須擴展一下這個名字以讓它具有唯一性。

我們可以通過sn.exe或VS對項目右鍵屬性在簽名選項卡中采取RSA算法對程序集進行數字簽名(加密:公鑰加密,私鑰解密。簽名:私鑰簽名,公鑰驗證簽名),會將構成程序集的所有文件通過哈希算法生成哈希值,然后通過非對稱加密算法用私鑰簽名,最后公布公鑰生成一串token,最終將生成一個由程序集名稱、版本號、語言文化、公鑰組成的唯一標識,它相當于一個強化的名稱,即強名稱程序集。? mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

我們日常在VS中的項目默認都沒有被簽名,所以就是弱名稱程序集。強名稱程序集是具有唯一標識性的程序集,并且可以通過對比哈希值來比較程序集是否被篡改,不過仍然有很多手段和軟件可以去掉程序集的簽名。

需要值得注意的一點是:當你試圖在已生成好的強名稱程序集中引用弱名稱程序集,那么你必須對弱名稱程序集進行簽名并在強名稱程序集中重新注冊。? 之所以這樣是因為一個程序集是否被篡改還要考慮到該程序集所引用的那些程序集,根據CLR搜索程序集的規則(下文會介紹),沒有被簽名的程序集可以被隨意替換,所以考慮到安全性,強名稱程序集必須引用強名稱程序集,否則就會報錯:需要強名稱程序集。

.NET Framework 4.5中對強簽名的更改:https://docs.microsoft.com/zh-cn/dotnet/framework/app-domains/enhanced-strong-naming

程序集搜索規則

事實上,按照存儲位置來說,程序集分為共享(全局)程序集和私有程序集。

CLR查找程序集的時候,會先判斷該程序集是否被強簽名,如果強簽名了那么就會去共享程序集的存儲位置(后文的GAC)去找,如果沒找到或者該程序集沒有被強簽名,那么就從該程序集的同一目錄下去尋找。

強名稱程序集是先找到與程序集名稱(VS中對項目右鍵屬性應用程序->程序集名稱)相等的文件名稱,然后 按照唯一標識再來確認,確認后CLR加載程序集,同時會通過公鑰效驗該簽名來驗證程序集是否被篡改(如果想跳過驗證可查閱https://docs.microsoft.com/zh-cn/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature),如果強名稱程序集被篡改則報錯。

而弱名稱程序集則直接按照與程序集名稱相等的文件名稱來找,如果還是沒有找到就以該程序集名稱為目錄的文件夾下去找。總之,如果最終結果就是沒找到那就會報System.IO.FileNotFoundException異常,即嘗試訪問磁盤上不存在的文件失敗時引發的異常。

注意:此處文件名稱和程序集名稱是兩個概念,不要模棱兩可,文件CLR頭內嵌程序集名稱。

舉個例子: 我有一個控制臺程序,其路徑為D:\Demo\Debug\demo.exe,通過該程序的元數據得知,其引用了一個程序集名稱為aa的普通程序集,引用了一個名為bb的強名稱程序集,該bb.dll的強名稱標識為:xx001。 現在CLR開始搜索程序集aa,首先它會從demo.exe控制臺的同一目錄(也就是D:\Demo\Debug\)中查找程序集aa,搜索文件名為aa.dll的文件,如果沒找到就在該目錄下以程序集名稱為目錄的目錄中查找,也就是會查 D:\Demo\Debug\aa\aa.dll,這也找不到那就報錯。 然后CLR開始搜索程序集bb,CLR從demo.exe的元數據中發現bb是強名稱程序集,其標識為:xx001。于是CLR會先從一個被定義為GAC的目錄中去通過標識找,沒找到的話剩下的尋找步驟就和尋找aa一樣完全一致了。? ? ?

當然,你也可以通過配置文件config中(配置文件存在于應用程序的同一目錄中)人為增加程序集搜索規則: 1.在運行時runtime節點中,添加privatePath屬性來添加搜索目錄,不過只能填寫相對路徑:?

<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><probing privatePath="relative1;relative2;" /> //程序集當前目錄下的相對路徑目錄,用;號分割 </assemblyBinding> </runtime>

2.如果程序集是強簽名后的,那么可以通過codeBase來指定網絡路徑或本地絕對路徑。

<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" /> <codeBase version="2.0.0.0" href="http://www.litwareinc.com/myAssembly.dll" /> </dependentAssembly> </assemblyBinding> </runtime>

當然,我們還可以在代碼中通過AppDomain類中的幾個成員來改變搜索規則,如AssemblyResolve事件、AppDomainSetup類等。

有關運行時節點的描述:https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/runtime-element

項目的依賴順序

如果沒有通過config或者在代碼中來設定CLR搜索程序集的規則,那么CLR就按照默認的也就是我上述所說的模式來尋找。 所以如果我們通過csc.exe來編譯項目,引用了其它程序集的話,通常需要將那些程序集復制到同一目錄下。故而每當我們通過VS編譯器對項目右鍵重新生成項目(重新編譯)時,VS都會將引用的程序集給復制一份到項目bin\輸出目錄Debug文件夾下,我們可以通過VS中對引用的程序集右鍵屬性-復制本地 True/Flase 來決定這一默認行為。

值得一提的是,項目間的生成是有序生成的,它取決于項目間的依賴順序。 比如Web項目引用BLL項目,BLL項目引用了DAL項目。那么當我生成Web項目的時候,因為我要注冊Bll程序集,所以我要先生成Bll程序集,而BLL程序集又引用了Dal,所以又要先生成Dal程序集,所以程序集生成順序就是Dal=>BLL=>Web,項目越多編譯的時間就越久。

程序集之間的依賴順序決定了編譯順序,所以在設計項目間的分層劃分時不僅要體現出層級職責,還要考慮到依賴順序。代碼存放在哪個項目要有講究,不允許出現互相引用的情況,比如A項目中的代碼引用B,B項目中的代碼又引用A。

為什么Newtonsoft.Json版本不一致?

而除了注意編譯順序外,我們還要注意程序集間的版本問題,版本間的錯亂會導致程序的異常。

舉個經典的例子:Newtonsoft.Json的版本警告,大多數人都知道通過版本重定向來解決這個問題,但很少有人會琢磨為什么會出現這個問題,找了一圈文章,沒找到一個解釋的。

比如: A程序集引用了 C盤:\Newtonsoft.Json 6.0程序集 B程序集引用了 從Nuget下載下來的Newtonsoft.Json 10.0程序集 此時A引用B,就會報:發現同一依賴程序集的不同版本間存在無法解決的沖突 這一警告。

A:引用Newtonsoft.Json 6.0Func(){var obj= Newtonsoft.Json.Obj;B.JsonObj();}B: 引用Newtonsoft.Json 10.0 JsonObj() { return Newtonsoft.Json.Obj; }

A程序集中的Func方法調用了B程序集中的JsonObj方法,JsonObj方法又調用了Newtonsoft.Json 10.0程序集中的對象,那么當執行Func方法時程序就會異常,報System.IO.FileNotFoundException: 未能加載文件或程序集Newtonsoft.Json 10.0的錯誤。

這是為什么? 1.這是因為依賴順序引起的。A引用了B,首先會先生成B,而B引用了 Newtonsoft.Json 10.0,那么VS就會將源引用文件(Newtonsoft.Json 10.0)復制到B程序集同一目錄(bin/Debug)下,名為Newtonsoft.Json.dll文件,其內嵌程序集版本為10.0。 2.然后A引用了B,所以會將B程序集和B程序集的依賴項(Newtonsoft.Json.dll)給復制到A的程序集目錄下,而A又引用了C盤的Newtonsoft.Json 6.0程序集文件,所以又將C:\Newtonsoft.Json.dll文件給復制到自己程序集目錄下。因為兩個Newtonsoft.Json.dll重名,所以直接覆蓋了前者,那么只保留了Newtonsoft.Json 6.0。 3.當我們調用Func方法中的B.Convert()時候,CLR會搜索B程序集,找到后再調用 return Newtonsoft.Json.Obj 這行代碼,而這行代碼又用到了Newtonsoft.Json程序集,接下來CLR搜索Newtonsoft.Json.dll,文件名稱滿足,接下來CLR判斷其標識,發現版本號是6.0,與B程序集清單里注冊的10.0版本不符,故而才會報出異常:未能加載文件或程序集Newtonsoft.Json 10.0。

以上就是為何Newtonsoft.Json版本不一致會導致錯誤的原因,其也詮釋了CLR搜索程序集的一個過程。 那么,如果我執意如此,有什么好的解決方法能讓程序順利執行呢?有,有2個方法。

第一種:通過bindingRedirect節點重定向,即當找到10.0的版本時,給定向到6.0版本

View Code

如何在編譯時加載兩個相同的程序集?

注意:我看過有的文章里寫的一個AppDomain只能加載一個相同的程序集,很多人都以為不能同時加載2個不同版本的程序集,實際上CLR是可以同時加載Newtonsoft.Json 6.0和Newtonsoft.Json 10.0的。

第二種:對每個版本指定codeBase路徑,然后分別放上不同版本的程序集,這樣就可以加載兩個相同的程序集。

View Code

如何同時調用兩個兩個相同命名空間和類型的程序集?

除了程序集版本不同外,還有一種情況就是,我一個項目同時引用了程序集A和程序集B,但程序集A和程序集B中的命名空間和類型名稱完全一模一樣,這個時候我調用任意一個類型都無法區分它是來自于哪個程序集的,那么這種情況我們可以使用extern alias外部別名。 我們需要在所有代碼前定義別名,extern alias a;extern alias b;,然后在VS中對引用的程序集右鍵屬性-別名,分別將其更改為a和b(或在csc中通過/r:{別名}={程序集}.dll)。 在代碼中通過 {別名}::{命名空間}.{類型}的方式來使用。 extern-alias介紹:?https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/extern-alias

共享程序集GAC

我上面說了這么多有關CLR加載程序集的細節和規則,事實上,類似于mscorlib.dll、System.dll這樣的FCL類庫被引用的如此頻繁,它已經是我們.NET編程中必不可少的一部分,幾盡每個項目都會引用,為了不再每次使用的時候都復制一份,所以計算機上有一個位置專門存儲這些我們都會用到的程序集,叫做全局程序集緩存(Global Assembly Cache,GAC),這個位置一般位于C:\Windows\Microsoft.NET\assembly和3.5之前版本的C:\Windows\assembly。 既然是共享存放的位置,那不可避免的會遇到文件名重復的情況,那么為了杜絕該類情況,規定在GAC中只能存在強名稱程序集,每當CLR要加載強名稱程序集時,會先通過標識去GAC中查找,而考慮到程序集文件名稱一致但版本文化等復雜的情況,所以GAC有自己的一套目錄結構。我們如果想將自己的程序集放入GAC中,那么就必須先簽名,然后通過如gacutil.exe工具(其存在于命令行工具中?https://docs.microsoft.com/zh-cn/dotnet/framework/tools/developer-command-prompt-for-vs中)來注冊至GAC中,值得一提的是在將強名稱程序集安裝在GAC中,會效驗簽名。

GAC工具:?https://docs.microsoft.com/en-us/dotnet/framework/tools/gacutil-exe-gac-tool

延伸

CLR是按需加載程序集的,沒有執行代碼也就沒有調用相應的指令,沒有相應的指令,CLR也不會對其進行相應的操作。 當我們執行Environment.CurrentDirectory這段代碼的時候,CLR首先要獲取Environment類型信息,通過自身元數據得知其存在mscorlib.dll程序集中,所以CLR要加載該程序集,而mscorlib.dll又由于其地位特殊,早在CLR初始化的時候就已經被類型加載器自動加載至內存中,所以這行代碼可以直接在內存中讀取到類型的方法信息。 在這個章節,我雖然描述了CLR搜索程序集的規則,但事實上,加載程序集讀取類型信息遠遠沒有這么簡單,這涉及到了屬于.NET Framework獨有的"應用程序域"概念和內存信息的查找。

簡單延伸兩個問題,mscorlib.dll被加載在哪里?內存堆中又是什么樣的一個情況?

應用程序域

傳統非托管程序是直接承載在Windows進程中,托管程序是承載在.NET虛擬機CLR上的,而在CLR中管控的這部分資源中,被分成了一個個邏輯上的分區,這個邏輯分區被稱為應用程序域,是.NET Framework中定義的一個概念。 因為堆內存的構建和刪除都通過GC去托管,降低了人為出錯的幾率,在此特性基礎上.NET強調在一個進程中通過CLR強大的管理建立起對資源邏輯上的隔離區域,每個區域的應用程序互不影響,從而讓托管代碼程序的安全性和健壯性得到了提升。

熟悉程序集加載規則和AppDomain是在.NET技術下進行插件編程的前提。AppDomain這部分概念并不復雜。 當啟動一個托管程序時,最先啟動的是CLR,在這過程中會通過代碼初始化三個邏輯區域,最先是SystemDomain系統程序域,然后是SharedDoamin共享域,最后是{程序集名稱}Domain默認域。

系統程序域里維持著一些系統構建項,我們可以通過這些項來監控并管理其它應用程序域等。共享域存放著其它域都會訪問到的一些信息,當共享域初始化完畢后,會自動加載mscorlib.dll程序集至該共享域。而默認域則用儲存自身程序集的信息,我們的主程序集就會被加載至這個默認域中,執行程序入口方法,在沒有特殊動作外所產生的一切耗費都發生在該域。

我們可以在代碼中創建和卸載應用程序域,域與域之間有隔離性,掛掉A域不會影響到B域,并且對于每一個加載的程序集都要指定域的,沒有在代碼中指定域的話,默認都是加載至默認域中。 AppDomain可以想象成組的概念,AppDomain包含了我們加載的一組程序集。我們通過代碼卸載AppDomain,即同時卸載了該AppDomain中所加載的所有程序集在內存中的相關區域。

AppDomain的初衷是邊緣隔離,它可以讓程序不重新啟動而長時間運行,圍繞著該概念建立的體系從而讓我們能夠使用.NET技術進行插件編程。

當我們想讓程序在不關閉不重新部署的情況下添加一個新的功能或者改變某一塊功能,我們可以這樣做:將程序的主模塊仍默認加載至默認域,再創建一個新的應用程序域,然后將需要更改或替換的模塊的程序集加載至該域,每當更改和替換的時候直接卸載該域即可。 而因為域的隔離性,我在A域和B域加載同一個程序集,那么A域和B域就會各存在內存地址不同但數據相同的程序集數據。

跨邊界訪問

事實上,在開發中我們還應該注意跨域訪問對象的操作(即在A域中的程序集代碼直接調用B域中的對象)是與平常編程中有所不同的,一個域中的應用程序不能直接訪問另一個域中的代碼和數據,對于這樣的在進程內跨域訪問操作分兩類。

一是按引用封送,需要繼承System.MarshalByRefObject,傳遞的是該對象的代理引用,與源域有相同的生命周期。 二是按值封送,需要被[Serializable]標記,是通過序列化傳遞的副本,副本與源域的對象無關。 無論哪種方式都涉及到兩個域直接的封送、解封,所以跨域訪問調用不適用于過高頻率。 (比如,原來你是這樣調用對象: var user=new User(); 現在你要這樣:var user=(User){應用程序域對象實例}.CreateInstanceFromAndUnwrap("Model.dll","Model.User"); )

值得注意的是,應用程序域是對程序集的組的劃分,它與進程中的線程是兩個一橫一豎,方向不一樣的概念,不應該將這2個概念放在一起比較。我們可以通過Thread.GetDomain來查看執行線程所在的域。 應用程序域在類庫中是System.AppDomain類,部分重要的成員有:

獲取當前 System.Threading.Thread 的當前應用程序域public static AppDomain CurrentDomain { get; }使用指定的名稱新建應用程序域public static AppDomain CreateDomain(string friendlyName); 卸載指定的應用程序域。 public static void Unload(AppDomain domain); 指示是否對當前進程啟用應用程序域的 CPU 和內存監視,開啟后可以根據相關屬性進行監控 public static bool MonitoringIsEnabled { get; set; } 當前域托管代碼拋出異常時最先發生的一個事件,框架設計中可以用到 public event EventHandler<FirstChanceExceptionEventArgs> FirstChanceException; 當某個異常未被捕獲時調用該事件,如代碼里只catch了a異常,實際產生的是 b異常,那么b異常就沒有捕捉到。 public event UnhandledExceptionEventHandler UnhandledException; 為指定的應用程序域屬性分配指定值。該應用程序域的局部存儲值,該存儲不劃分上下文和線程,均可通過GetData獲取。 public void SetData(string name, object data); 如果想使用托管代碼來覆蓋CLR的默認行為https://msdn.microsoft.com/zh-cn/library/system.appdomainmanager(v=vs.85).aspx public AppDomainManager DomainManager { get; } 返回域的配置信息,如在config中配置的節點信息 public AppDomainSetup SetupInformation { get; }

應用程序域:?https://docs.microsoft.com/zh-cn/dotnet/framework/app-domains/application-domains

AppDomain和AppPool

注意:此處的AppDomain應用程序域 和 IIS中的AppPool應用程序池 是2個概念,AppPool是IIS獨有的概念,它也相當于一個組的概念,對網站進行劃組,然后對組進行一些如進程模型、CPU、內存、請求隊列的高級配置。

內存

應用程序域把資源給隔離開,這個資源,主要指內存。那么什么是內存呢?

要知道,程序運行的過程就是電腦不斷通過CPU進行計算的過程,這個過程需要讀取并產生運算的數據,為此我們需要一個擁有足夠容量能夠快速與CPU交互的存儲容器,這就是內存了。對于內存大小,32位處理器,尋址空間最大為2的32次方byte,也就是4G內存,除去操作系統所占用的公有部分,進程大概能占用2G內存,而如果是64位處理器,則是8T。

而在.NET中,內存區域分為堆棧和托管堆。

堆棧和堆的區別

堆和堆棧就內存而言只不過是地址范圍的區別。不過堆棧的數據結構和其存儲定義讓其在時間和空間上都緊密的存儲,這樣能帶來更高的內存密度,能在CPU緩存和分頁系統表現的更好。故而訪問堆棧的速度總體來說比訪問堆要快點。

線程堆棧

操作系統會為每條線程分配一定的空間,Windwos為1M,這稱之為線程堆棧。在CLR中的棧主要用來執行線程方法時,保存臨時的局部變量和函數所需的參數及返回的值等,在棧上的成員不受GC管理器的控制,它們由操作系統負責分配,當線程走出方法后,該棧上成員采用后進先出的順序由操作系統負責釋放,執行效率高。 而托管堆則沒有固定容量限制,它取決于操作系統允許進程分配的內存大小和程序本身對內存的使用情況,托管堆主要用來存放對象實例,不需要我們人工去分配和釋放,其由GC管理器托管。

為什么值類型存儲在棧上

不同的類型擁有不同的編譯時規則和運行時內存分配行為,我們應知道,C# 是一種強類型語言,每個變量和常量都有一個類型,在.NET中,每種類型又被定義為值類型或引用類型。

使用 struct、enum 關鍵字直接派生于System.ValueType定義的類型是值類型,使用 class、interface、delagate 關鍵字派生于System.Object定義的類型是引用類型。 對于在一個方法中產生的值類型成員,將其值分配在棧中。這樣做的原因是因為值類型的值其占用固定內存的大小。

C#中int關鍵字對應BCL中的Int32,short對應Int16。Int32為2的32位,如果把32個二進制數排列開來,我們要求既能表達正數也能表達負數,所以得需要其中1位來表達正負,首位是0則為+,首位是1則為-,那么我們能表示數據的數就只有31位了,而0是介于-1和1之間的整數,所以對應的Int32能表現的就是2的31次方到2的31次方-1,即2147483647和-2147483648這個整數段。

1個字節=8位,32位就是4個字節,像這種以Int32為代表的值類型,本身就是固定的內存占用大小,所以將值類型放在內存連續分配的棧中。

托管堆模型

而引用類型相比值類型就有點特殊,newobj創建一個引用類型,因其類型內的引用對象可以指向任何類型,故而無法準確得知其固定大小,所以像對于引用類型這種無法預知的容易產生內存碎片的動態內存,我們把它放到托管堆中存儲。

托管堆由GC托管,其分配的核心在于堆中維護著一個nextObjPtr指針,我們每次實例(new)一個對象的時候,CLR將對象存入堆中,并在棧中存放該對象的起始地址,然后該指針都會根據該對象的大小來計算下一個對象的起始地址。不同于值類型直接在棧中存放值,引用類型則還需要在棧中存放一個代表(指向)堆中對象的值(地址)。

而托管堆又可以因存儲規則的不同將其分類,托管堆可以被分為3類:

  • 1.用于托管對象實例化的垃圾回收堆,又以存儲對象大小分為小對象(<85000byte)的GC堆(SOH,Small Object Heap)和用于存儲大對象實例的(>=85000byte)大對象堆(LOG,Larage Object Heap)。
  • 2.用于存儲CLR組件和類型系統的加載(Loader)堆,其中又以使用頻率分為經常訪問的高頻堆(里面包含有MethodTables方法表, MeghodDescs方法描述, FieldDescs方法描述和InterfaceMaps接口圖),和較低的低頻堆,和Stub堆(輔助代碼,如JIT編譯后修改機器代碼指令地址環節)。
  • 3.用于存儲JIT代碼的堆及其它雜項的堆。

加載程序集就是將程序集中的信息給映射在加載堆,對產生的實例對象存放至垃圾回收堆。前文說過應用程序域是指通過CLR管理而建立起的邏輯上的內存邊界,那么每個域都有其自己的加載堆,只有卸載應用程序域的時候,才會回收該域對應的加載堆。

而加載堆中的高頻堆包含的有一個非常重要的數據結構表---方法表,每個類型都僅有一份方法表(MethodTables),它是對象的第一個實例創建前的類加載活動的結果,它主要包含了我們所關注的3部分信息:

  • 1包含指向EEClass的一個指針。EEClass是一個非常重要的數據結構,當類加載器加載到該類型時會從元數據中創建出EEClass,EEClass里主要存放著與類型相關的表達信息。
  • 2包含指向各自方法的方法描述器(MethodDesc)的指針邏輯組成的線性表信息:繼承的虛函數, 新虛函數, 實例方法, 靜態方法。
  • 3包含指向靜態字段的指針。

那么,實例一個對象,CLR是如何將該對象所對應的類型行為及信息的內存位置(加載堆)關聯起來的呢?

原來,在托管堆上的每個對象都有2個額外的供于CLR使用的成員,我們是訪問不到的,其中一個就是類型對象指針,它指向位于加載堆中的方法表從而讓類型的狀態和行為關聯了起來, 類型指針的這部分概念我們可以想象成obj.GetType()方法獲得的運行時對象類型的實例。而另一個成員就是同步塊索引,其主要用于2點:1.關聯內置SyncBlock數組的項從而完成互斥鎖等目的。 2.是對象Hash值計算的輸入參數之一。

上述gif是我簡單畫的一個圖,可以看到對于方法中申明的值類型變量,其在棧中作為一塊值表示,我們可以直接通過c#運算符sizeof來獲得值類型所占byte大小。而方法中申明的引用類型變量,其在托管堆中存放著對象實例(對象實例至少會包含上述兩個固定成員以及實例數據,可能),在棧中存放著指向該實例的地址。

當我new一個引用對象的時候,會先分配同步塊索引(也叫對象頭字節),然后是類型指針,最后是類型實例數據(靜態字段的指針存在于方法表中)。會先分配對象的字段成員,然后分配對象父類的字段成員,接著再執行父類的構造函數,最后才是本對象的構造函數。這個多態的過程,對于CLR來說就是一系列指令的集合,所以不能糾結new一個子類對象是否會也會new一個父類對象這樣的問題。而也正是因為引用類型的這樣一個特征,我們雖然可以估計一個實例大概占用多少內存,但對于具體占用的大小,我們需要專門的工具來測量。

對于引用類型,u2=u1,我們在賦值的時候,實際上賦的是地址,那么我改動數據實際上是改動該地址指向的數據,這樣一來,因為u2和u1都指向同一塊區域,所以我對u1的改動會影響到u2,對u2的改動會影響到u1。如果我想互不影響,那么我可以繼承IClone接口來實現內存克隆,已有的CLR實現是淺克隆方法,但也只能克隆值類型和String(string是個特殊的引用類型,對于string的更改,其會產生一個新實例對象),如果對包含其它引用類型的這部分,我們可以自己通過其它手段實現深克隆,如序列化、反射等方式來完成。而如果引用類型中包含有值類型字段,那么該字段仍然分配在堆上。

對于值類型,a=b,我們在賦值的時候,實際上是新建了個值,那么我改動a的值那就只會改動a的值,改動b的值就只會改動b的值。而如果值類型(如struct)中包含的有引用類型,那么仍是同樣的規則,引用類型的那部分實例在托管堆中,地址在棧上。

我如果將值類型放到引用類型中(如:object a=3),會在棧中生成一個地址,在堆中生成該值類型的值對象,還會再生成這類型指針和同步塊索引兩個字段,這也就是常說裝箱,反過來就是拆箱。每一次的這樣的操作,都會涉及到內存的分布、拷貝,可見,裝箱和拆箱是有性能損耗,因此應該減少值類型和引用類型之間轉換的次數。? 但對于引用類型間的子類父類的轉換,僅是指令的執行消耗,幾盡沒有開銷。

選class還是struct

那么我到底是該new一個class呢還是選擇struct呢?

通過上文知道對于class,用完之后對象仍然存在托管堆,占用內存。對于struct,用完之后直接由操作系統銷毀。那么在實際開發中定義類型時,選擇class還是struct就需要注意了,要綜合應用場景來辨別。struct存在于棧上,棧和托管堆比較,最大的優勢就是即用即毀。所以如果我們單純的傳遞一個類型,那么選擇struct比較合適。但須注意線程堆棧有容量限制,不可多存放超大量的值類型對象,并且因為是值類型直接傳遞副本,所以struct作為方法參數是線程安全的,但同樣要避免裝箱的操作。而相比較class,如果類型中還需要多一些封裝繼承多態的行為,那么class當然是更好的選擇。

GC管理器

值得注意的是,當我new完一個對象不再使用的時候,這個對象在堆中所占用的內存如何處理? 在非托管世界中,可以通過代碼手動進行釋放,但在.NET中,堆完全由CLR托管,也就是說GC堆是如何具體來釋放的呢?

當GC堆需要進行清理的時候,GC收集器就會通過一定的算法來清理堆中的對象,并且版本不同算法也不同。最主要的則為Mark-Compact標記-壓縮算法。 這個算法的大概含義就是,通過一個圖的數據結構來收集對象的根,這個根就是引用地址,可以理解為指向托管堆的這根關系線。當觸發這個算法時,會檢查圖中的每個根是否可達,如果可達就對其標記,然后在堆上找到剩余沒有標記(也就是不可達)的對象進行刪除,這樣,那些不在使用的堆中對象就刪除了。

前面說了,因為nextObjPtr的緣故,在堆中分配的對象都是連續分配的,因為未被標記而被刪除,那么經過刪除后的堆就會顯得支零破碎,那么為了避免空間碎片化,所以需要一個操作來讓堆中的對象再變得緊湊、連續,而這樣一個操作就叫做:Compact壓縮。? 而對堆中的分散的對象進行挪動后,還會修改這些被挪動對象的指向地址,從而得以正確的訪問,最后重新更新一下nextObjPtr指針,周而復始。

而為了優化內存結構,減少在圖中搜索的成本,GC機制又為每個托管堆對象定義了一個屬性,將每個對象分成了3個等級,這個屬性就叫做:代,0代、1代、2代。

每當new一個對象的時候,該對象都會被定義為第0代,當GC開始回收的時候,先從0代回收,在這一次回收動作之后,0代中沒有被回收的對象則會被定義成第1代。當回收第1代的時候,第1代中沒有被清理掉的對象就會被定義到第2代。? CLR初始化時會為0/1/2這三代選擇一個預算的容量。0代通常以256 KB-4 MB之間的預算開始,1代的典型起始預算為512 KB-4 MB,2代不受限制,最大可擴展至操作系統進程的整個內存空間。

比如第0代為256K,第1代為2MB。我們不停的new對象,直到這些對象達到256k的時候,GC會進行一次垃圾回收,假設這次回收中回收了156k的不可達對象,剩余100k的對象沒有被回收,那么這100k的對象就被定義為第1代。現在就變成了第0代里面什么都沒有,第1代里放的有100k的對象。這樣周而復始,GC清除的永遠都只有第0代對象,除非當第一代中的對象累積達到了定義的2MB的時候,才會連同清理第1代,然后第1代中活著的部分再升級成第二代...

第二代的容量是沒有限制,但是它有動態的閾值(因為等到整個內存空間已滿以執行垃圾回收是沒有意義的),當達到第二代的閾值后會觸發一次0/1/2代完整的垃圾收集。

也就是說,代數越長說明這個對象經歷了回收的次數也就越多,那么也就意味著該對象是不容易被清除的。? 這種分代的思想來將對象分割成新老對象,進而配對不同的清除條件,這種巧妙的思想避免了直接清理整個堆的尷尬。

弱引用、弱事件

GC收集器會在第0代飽和時開始回收托管堆對象,對于那些已經申明或綁定的不經訪問的對象或事件,因為不經常訪問而且還占內存(有點懶加載的意思),所以即時對象可達,但我想在GC回收的時候仍然對其回收,當需要用到的時候再創建,這種情況該怎么辦?

那么這其中就引入了兩個概念: WeakReference弱引用、WeakEventManager弱事件 對于這2兩個不區分語言的共同概念,大家可自行擴展百度,此處就不再舉例。

GC堆回收

那么除了通過new對象而達到代的閾(臨界)值時,還有什么能夠導致垃圾堆進行垃圾回收呢? 還可能windows報告內存不足、CLR卸載AppDomain、CLR關閉等其它特殊情況。

或者,我們還可以自己通過代碼調用。

.NET有GC來幫助開發人員管理內存,并且版本也在不斷迭代。GC幫我們托管內存,但仍然提供了System.GC類讓開發人員能夠輕微的協助管理。 這其中有一個可以清理內存的方法(并沒有提供清理某個對象的方法):GC.Collect方法,可以對所有或指定代進行即時垃圾回收(如果想調試,需在release模式下才有效果)。這個方法盡量別用,因為它會擾亂代與代間的秩序,從而讓低代的垃圾對象跑到生命周期長的高代中。

GC還提供了,判斷當前對象所處代數、判斷指定代數經歷了多少次垃圾回收、獲取已在托管堆中分配的字節數這樣的三個方法,我們可以從這3個方法簡單的了解托管堆的情況。

托管世界的內存不需要我們打理,我們無法從代碼中得知具體的托管對象的大小,你如果想追求對內存最細微的控制,顯然C#并不適合你,不過類似于有關內存把控的這部分功能模塊,我們可以通過非托管語言來編寫,然后通過.NET平臺的P/Invoke或COM技術(微軟為CLR定義了COM接口并在注冊表中注冊)來調用。

像FCL中的源碼,很多涉及到操作系統的諸如 文件句柄、網絡連接等外部extren的底層方法都是非托管語言編寫的,對于這些非托管模塊所占用的資源,我們可以通過隱式調用析構函數(Finalize)或者顯式調用的Dispose方法通過在方法內部寫上非托管提供的釋放方法來進行釋放。

像文中示例的socket就將釋放資源的方法寫入Dispose中,析構函數和Close方法均調用Dispose方法以此完成釋放。事實上,在FCL中的使用了非托管資源的類大多都遵循IDispose模式。而如果你沒有釋放非托管資源直接退出程序,那么操作系統會幫你釋放該程序所占的內存的。

垃圾回收對性能的影響

還有一點,垃圾回收是對性能有影響的。 GC雖然有很多優化策略,但總之,只要當它開始回收垃圾的時候,為了防止線程在CLR檢查期間對對象更改狀態,所以CLR會暫停進程中的幾乎所有線程(所以線程太多也會影響GC時間),而暫停的時間就是應用程序卡死的時間,為此,對于具體的處理細節,GC提供了2種配置模式讓我們選擇。

第一種為:單CPU的工作站模式,專為單CPU處理器定做。這種模式會采用一系列策略來盡可能減少GC回收中的暫停時間。? 而工作站模式又分為并發(或后臺)與不并發兩種,并發模式表現為響應時間快速,不并發模式表現為高吞吐量。

第二種為:多CPU的服務器模式,它會為每個CPU都運行一個GC回收線程,通過并行算法來使線程能真正同時工作,從而獲得性能的提升。

我們可以通過在Config文件中更改配置來修改GC模式,如果沒有進行配置,那么應用程序總是默認為單CPU的工作站的并發模式,并且如果機器為單CPU的話,那么配置服務器模式則無效。

如果在工作站模式中想禁用并發模式,則應該在config中運行時節點添加 <gcConcurrent enabled="false" />? 如果想更改至服務器模式,則可以添加 <gcServer enabled="true" />。

<configuration><runtime><!--<gcConcurrent enabled="true|false"/>--><!--<gcServer enabled="true|false"/>--> </runtime> </configuration>

gcConcurrent:?https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcconcurrent-element? gcServer:?https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcserver-element

性能建議

雖然我們可以選擇適合的GC工作模式來改善垃圾回收時的表現,但在實際開發中我們更應該注意減少不必要的內存開銷。

幾個建議是,減換需要創建大量的臨時變量的模式、考慮對象池、大對象使用懶加載、對固定容量的集合指定長度、注意字符串操作、注意高頻率的隱式裝箱操作、延遲查詢、對于不需要面向對象特性的類用static、需要高性能操作的算法改用外部組件實現(p/invoke、com)、減少throw次數、注意匿名函數捕獲的外部對象將延長生命周期、可以閱讀GC相關運行時配置在高并發場景注意變換GC模式...

對于.NET中改善性能可延伸閱讀?https://msdn.microsoft.com/zh-cn/library/ms973838.aspx?、?https://msdn.microsoft.com/library/ms973839.aspx

.NET程序執行圖

至此,.NET Framework上的三個重要概念,程序集、應用程序域、內存在本文講的差不多了,我畫了一張圖簡單的概述.NET程序的一個執行流程:

對于后文,我將單獨的介紹一些其它雜項,首先是.NET平臺的安全性。

.NET的安全性

.NET Framework中的安全機制分為 基于角色的安全機制 和 代碼訪問安全機制 。

基于角色的安全性

基于角色的安全機制作為傳統的訪問控制,其運用的非常廣泛,如操作系統的安全策略、數據庫的安全策略等等...它的概念就相當于我們經常做的那些RBAC權限管理系統一樣,用戶關聯角色,角色關聯權限,權限對應著操作。 整個機制的安全邏輯就和我們平時編寫代碼判斷是一樣的,大致可以分為兩個步驟.

第一步就是創建一個主體,然后標識這個主體是什么身份(角色) ,第二步就是 身份驗證,也就是if判斷該身份是否可以這樣操作。

而在.NET Framework中,這主體可以是Windows賬戶,也可以是自定義的標識,通過生成如當前線程或應用程序域使用的主體相關的信息來支持授權。 比如,構造一個代表當前登錄賬戶的主體對象WindowsPrincipal,然后通過 AppDomain.CurrentDomain.SetThreadPrincipal(主體對象);或Thread.CurrentPrincipal的set方法來設置應用程序域或線程的主體對象, 最后使用System.Security.Permissions.PrincipalPermission特性來標記在方法上來進行授權驗證。

如圖,我當前登錄賬號名稱為DemoXiaoZeng,然后通過Thread.CurrentPrincipal設置當前主體,執行aa方法,順利打印111。如果檢測到PrincipalPermission類中的Name屬性值不是當前登錄賬號,那么就報錯:對主體權限請求失敗。?

在官方文檔中有對.NET Framework基于角色的安全性的詳細的介紹,感興趣可以去了解?https://docs.microsoft.com/zh-cn/dotnet/standard/security/principal-and-identity-objects#principal-objects

代碼訪問安全性

在.NET Framework中還有一個安全策略,叫做 代碼訪問安全Code Access Security,也就是CAS了。

代碼訪問安全性在.NET Framework中是用來幫助限制代碼對受保護資源和操作的訪問權限。 舉個例子,我通過創建一個FileIOPermission對象來限制對后續代碼對D盤的文件和目錄的訪問,如果后續代碼對D盤進行資源操作則報錯。?

FileIOPermission是代碼控制訪問文件和文件夾的能力。除了FileIOPermission外,還有如PrintingPermission代碼控制訪問打印機的權限、RegistryPermission代碼控制操作注冊表的權限、SocketPermission控制接受連接或啟動Socket連接的權限。?

對于這些通過代碼來對受保護資源和操作的權限限制,也就是這些類名后綴為Permission的類,它們叫做 Permissions(權限),都繼承自CodeAccessPermission,都有如Demand,Assert,Deny,PermitOnly,IsSubsetOf,Intersect和Union這些方法,在MSDN上有完整的權限列表:https://msdn.microsoft.com/en-us/library/h846e9b3(v=vs.100).aspx

為了確定代碼是否有權訪問某一資源或執行某一操作,CLR的安全系統將審核調用堆棧,以將每個調用方獲得的權限與要求的權限進行比較。 如果調用堆棧中的任何調用方不具備要求的權限,則會引發安全性異常并拒絕訪問。

圖出自?https://docs.microsoft.com/zh-cn/dotnet/framework/misc/code-access-security

而除了Permissions權限,代碼訪問安全性機制還有 權限集、證據、代碼組、策略等概念。這些概念讓CAS如此強大,但相應的,它們也讓CAS變得復雜,必須為每個特定機器定義正確的PermissionSet和Code Groups才能設置成一個成功的CAS策略。

考慮到這層原因,Microsoft .NET安全小組決定從頭開始重建代碼訪問安全性。在.NET Framework4.0之后,就不再使用之前的那套CAS模型了,而是使用.NET Framework 2.0中引入的安全透明模型,然后稍加修改,修改后的安全透明模型成為保護資源的標準方法,被稱之為:安全透明度級別2

安全透明度2介紹:https://msdn.microsoft.com/en-us/library/dd233102(v=vs.100).aspx .NET Framework4.0的安全更改:https://msdn.microsoft.com/en-us/library/dd233103(v=vs.100).aspx? 一個完整的CAS演示:https://www.codeproject.com/Articles/5724/Understanding-NET-Code-Access-Security

對于安全透明度級別2我將不再介紹,感興趣的可以看我推薦的這2篇文章,對Level2的安全透明度介紹的比較詳細,包括實踐、遷移。? https://www.red-gate.com/simple-talk/dotnet/.net-framework/whats-new-in-code-access-security-in-.net-framework-4.0---part-i/ https://www.red-gate.com/simple-talk/dotnet/net-framework/whats-new-in-code-access-security-in-net-framework-4-0-part-2/

----------------------------------------------

須注意: .NET平臺上的安全機制,僅僅是.NET平臺上的,因此它只限制于托管代碼,我們可以直接調用非托管代碼或進程通信間接調用非托管代碼等多個手段來突破對托管代碼 操作資源的限制。

事實上,我們在平常項目中代碼編寫的安全機制(業務邏輯身份驗證、項目框架驗證)與這些平臺級的安全機制沒什么不同。我們可以理解為代碼寫的位置不一樣,.NET安全機制是寫在CLR組件中,而我們的安全機制是寫在上層的代碼中。這些平臺級的標識更多的是和操作系統用戶有關,而我們項目代碼中的標識則是和在數據庫中注冊的用戶有關, 大家都是通過if else來去判斷,判斷的主體和格局不一樣,邏輯本質都是相同的。

NET Core不支持代碼訪問安全性和安全性透明性。

.NET是什么

我在前文對.NET系統概述時,有的直接稱.NET,有的稱.NET Framework。那么準確來說什么是.NET?什么又是.NET Framework呢?

.NET是一個微軟搭造的開發者平臺,它主要包括:

  • 1.支持(面向)該平臺的編程語言(如C#、Visual Basic、C++/CLI、F#、IronPython、IronRuby...),
  • 2.用于該平臺下開發人員的技術框架體系(.NET Framework、.NET Core、Mono、UWP等),
    • 1.定義了通用類型系統,龐大的CTS體系
    • 2.用于支撐.NET下的語言運行時的環境:CLR
    • 3..NET體系技術的框架庫FCL
  • 3.用于支持開發人員開發的軟件工具(即SDK,如VS2017、VS Code等)

.NET Framework是什么

事實上,像我上面講的那些諸如程序集、GC、AppDomain這樣的為CLR的一些概念組成,實質上指的是.NET Framework CLR。

.NET平臺是微軟為了占據開發市場而成立的,不是無利益驅動的純技術平臺的那種東西。基于該平臺下的技術框架也因為 商業間的利益 從而和微軟自身的Windows操作系統所綁定。所以雖然平臺雄心和口號很大,但很多框架類庫技術都是以Windows系統為藍本,這樣就導致,雖然.NET各方面都挺好,但是用.NET就必須用微軟的東西,直接形成了技術-商業的綁定。

.NET Framework就是.NET 技術框架組成在Windows系統下的具體的實現,和Windows系統高度耦合,上文介紹的.NET系統,就是指.NET Framework。

部署.net Framework :https://docs.microsoft.com/zh-cn/dotnet/framework/deployment/deployment-guide-for-developers? .NET Framework高級開發:https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/29eafad8(v%3dvs.90)? .NET Framework源碼在線瀏覽:https://referencesource.microsoft.com/

如何在VS中調試.NET Framework源代碼

最為關鍵的是pdb符號文件,沒得符號就調不了,對于符號我們從微軟的符號服務器上下載(默認就已配置),還得有源代碼來調試。

點擊工具-選項-調試-常規,如果你之前沒有在該配置欄配置過,那么你就勾選 啟用源服務器支持 、啟用.net Framework源代碼單步執行,然后將 要求源文件與原始版本完全匹配 給取消掉。

然后就是下載pdb符號文件了,如果想直接下載那么可以在調試-符號這欄 將Microsoft符號服務器給勾上 。如果想按需下載,那么在調試的時候,可以點擊調試-窗口 選擇 模塊/調用堆棧 來選擇自己想加載的去加載。

然后至?https://referencesource.microsoft.com/網站 點擊右上角下載源代碼。當你調試代碼的時候,會提示你無可用源,這個時候你再將你下載下來的源碼文件給瀏覽查找一下就可以了。

如何配置VS來調試.NET Framework源碼:?https://referencesource.microsoft.com/#q=web?、?https://technet.microsoft.com/zh-cn/cc667410.aspx

還一種方法是,下載.NET Reflector插件,該插件可以幫助我們在VS中直接調試dll,這種方式操作非常簡單,不過該插件收費,具體的可以查看我之前寫過的文章(群里有該插件的注冊版)

.NET Core是什么

有丑才有美,有低才有高,概念是比較中誕生的。.NET Core就是如此,它是其它操作系統的.NET Framework翻版實現。

操作系統不止Windows,還有Mac和類Linux等系統, .NET的實現 如果按操作系統來橫向分割的話,可以分為 Windows系統下的 .NET Framework 和 兼容多個操作系統的 .NET Core。

我們知道,一個.NET程序運行核心在于.NET CLR,為了能讓.NET程序在其它平臺上運行,一些非官方社區和組織為此開發了在其它平臺下的.NET實現(最為代表的是mono,其團隊后來又被微軟給合并了 ),但因為不是官方,所以在一些方面多少有些缺陷(如FCL),后來微軟官方推出了.NET Core,其開源在Github中,并被收錄在NET基金會(.NET Foundation,由微軟公司成立與贊助的獨立自由軟件組織,其目前收錄包括.NET編譯器平臺("Roslyn")以及ASP.NET項目系列,.NET Core,Xamarin Forms以及其它流行的.NET開源框架),旨在真正的 .NET跨平臺。

.NET Core是.NET 技術框架組成在Windows.macOS.Linux系統下的具體的實現。 .NET Core是一個開源的項目,其由 Microsoft 和 GitHub 上的 .NET 社區共同維護,但 這份工作仍然是巨大的,因為在早期對.NET上的定義及最初的實現一直是以Windows系統為參照及載體,一些.NET機制實際上與Windows系統耦合度非常高,有些屬于.NET自己體系內的概念,有些則屬于Windows系統api的封裝。 那么從Windows轉到其它平臺上,不僅要實現相應的CLR,還要舍棄或重寫一部分BCL,因而,.NET Core在概念和在項目中的行為與我們平常有些不同。

比如,NET Core不支持AppDomains、遠程處理、代碼訪問安全性 (CAS) 和安全透明度,任何有關該概念的庫代碼都應該被替換。? 這部分代碼它不僅指你項目中的代碼,還指你項目中using的那些程序集代碼,所以你會在github上看到很多開源項目都在跟進對.NET Core的支持,并且很多開發者也嘗試學習.NET Core,這也是一種趨勢。

.NET Core指南https://docs.microsoft.com/en-us/dotnet/core/ .NET基金會:https://dotnetfoundation.org? .NET Core跨平臺的行為變更:https://github.com/dotnet/corefx/wiki/ApiCompat? 微軟宣布.NET開發環境將開源 :https://news.cnblogs.com/n/508410/

.NET Standard是什么

值得一提的是微軟還為BCL提出了一個標準,畢竟各式各樣的平臺,技術層出不窮,為了防止.NET在類庫方面的碎片化,即提出了一套正式的 .NET API (.NET 的應用程序編程接口)規范,.NET Standard。

正如上面CLS一樣,.NET Standard就類似于這樣的一個概念,無論是哪個托管框架,我們遵循這個標準,就能始終保持在BCL的統一性,即我不需要關心我是用的.NET Framework還是.NET Core,只要該類被定義于.NET Standard中,我就一定能在對應支持的.NET Standard的版本的托管框架中找到它。

.NET Standard:?https://docs.microsoft.com/zh-cn/dotnet/standard/net-standard#net-implementation-support

.NET Standard開源代碼:https://github.com/dotnet/standard

.NET官方開源項目鏈接

現在我將給出.NET相關的開源項目地址: 參與.NET和.NET開源項目的起點:https://github.com/Microsoft/dotnet

  • .NET Core:https://github.com/dotnet/core
  • .NET Core文檔:https://github.com/dotnet/docs
  • ASP.NET Core:https://github.com/aspnet/home
  • ASP.NET Core文檔:https://github.com/aspnet/Docs
  • EntityFramework Core框架:https://github.com/aspnet/EntityFrameworkCore
  • ASP.NET Core MVC框架:https://github.com/aspnet/Mvc
  • EntityFramework6:https://github.com/aspnet/EntityFramework6
  • .NET Framework源碼:https://github.com/microsoft/referencesource
  • .NET Core基類庫:https://github.com/dotnet/corefx
  • .NET Core CLR:https://github.com/dotnet/coreclr
  • Roslyn編譯器:https://github.com/dotnet/roslyn
  • MVC5、Web API2、Web Pages3框架源碼:https://github.com/aspnet/AspNetWebStack
  • .NET Standard:https://github.com/dotnet/standard
  • KestrelHttpServer用于ASP.NET Core的跨平臺Web服務器:https://github.com/aspnet/KestrelHttpServer
  • Visual Studio Code源碼:https://github.com/Microsoft/vscode
  • 一些優秀的.NET庫、工具、框架、軟件開源集合:https://github.com/quozd/awesome-dotnet
  • 一些常用框架對ASP.NET Core和.NET Core的支持報告:https://github.com/jpsingleton/ANCLAFS
  • 一些.NET下用于支持開發的開源項目集合:https://github.com/Microsoft/dotnet/blob/master/dotnet-developer-projects.md
  • 微軟出品的分布式框架orleans:https://github.com/dotnet/orleans
  • ML.NET 用于.NET的開源和跨平臺機器學習框架:https://github.com/dotnet/machinelearning

Visual Studio

在文章最后,我還要簡單的說下Visual Studio。

通過上文得知,只需要一個txt記事本+csc.exe我們就可以開發出一個.NET程序,那么與之相比,.NET提供的開發工具VS有什么不同呢?

我們用記事本+csc.exe來編寫一個.NET程序只適合小打小鬧,對于真正要開發一個項目而言,我們需要文件管理、版本管理、一個好的開發環境等。而vs ide則就是這樣一個集成代碼編輯、編譯、調試、追蹤、測試、部署、協作、插件擴展這樣多個組件的集成開發環境,csc.exe的編譯功能只是vs ide中的其中之一。使用vside開發可以節省大量的開發時間和成本。

sln解決方案

當你用VS來新建一個項目時,VS會先為你新建一個整體的解決方案。這個解決方案表現為.sln和.suo后綴格式的文件,它們均是文本文件,對解決方案右鍵屬性可以進行相應的修改,也可以直接用記事本打開。

在sln中,定義了解決方案的版本及環境,如包含的項目,方案啟動項,生成或部署的一些項目配置等,你可以通過修改或重新定義sln來更改你的整個解決方案。? 而suo則包含于解決方案建立關聯的選項,相當于快照,儲存了用戶界面的自定義配置、調試器斷點、觀察窗口設置等這樣的東西,它是隱藏文件,可刪除但建議不要刪除。

我們可以通過對比各版本之間的sln來修改sln,也可以使用網上的一些轉換工具,也可以直接點擊VS的文件-新建-從現有代碼創建項目來讓項目在不同VS版本間切換。? Visual Studio 2010 - # Visual Studio 4.0 Visual Studio 2012 - # Visual Studio 4.0 Visual Studio 2013 - # Visual Studio 12.00 Visual Studio 2015 - # Visual Studio 14 Visual Studio 2017 - # Visual Studio 15

項目模板

VS使用項目模板來基于用戶的選擇而創建新的項目,也就是新建項目中的那些展示項(如mvc5項目/winform項目等等),具體表現為包含.vstemplate及一些定義的關聯文件這樣的母版文件。將這些文件壓縮為一個 .zip 文件并放在正確的文件夾中時,就會在展示項中予以顯示。

用戶可以創建或自定義項目模板,也可以選擇現有的模板,比如我創建一個控制臺項目就會生成一個在.vstemplate中定義好的Program.cs、AssemblyInfo.cs(程序集級別的特性)、App.config、ico、csproj文件

csproj工程文件

這里面,csproj是我們最常見的核心文件,CSharp Project,它是用于構建這個項目的工程文件。

csproj是基于xml格式的MSBuild項目文件,其仍然是文本文件,可以打開并修改定義了的工程構造的屬性,比如選擇性的添加或刪除或修改包含在項目中的文件或引用、修改項目版本、將其轉換為其它類型項目等。

MSBuild是微軟定義的一個用于生成應用程序的平臺(Microsoft Build Engine),在這里為VS提供了項目的構造系統,在微軟官方文檔上有著詳細的說明:https://msdn.microsoft.com/zh-cn/library/dd393573.aspx、https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild

項目屬性雜項

現在,簡單說明一下csproj文件的一些核心元素。我們用vs新建一個控制臺項目,然后對項目右鍵屬性打開項目屬性,在應用程序頁我們可以定義:程序集名稱(生成出來的程序集以程序集名稱作為文件名,相當于csc中的/out)、默認命名空間(每次新建類里面顯示的命名空間)、目標框架、應用程序類型、程序集信息(AssemblyInfo中的信息)、啟動對象(可同時存在多個Main方法,需指定其中一個為入口對象)、程序集資源(一些可選的圖標及文件)

1.在生成頁有:

  • 條件編譯符號(全局的預編譯#define指令,不用在每個文件頭部定義,相當于csc中的/define)
  • 定義DEBUG/TRACE常量(用于調試輸出的定義變量,如智能追蹤的時候可以輸出該變量)
  • 目標平臺(指定當前面向什么處理器生成的程序集,相當于csc中的/platform。選擇x86則生成的程序集生成32位程序,能在32/64位Intel處理器中使用。選擇x64則生成64位,只能在64位系統中運行。選擇Any CPU則32位系統生成32位,64位系統則生成64位。注意:編譯平臺和目標調用平臺必須保持一致,否則報錯。生成的32位程序集不能調用64位程序集,64位也不能調用32位)、首選32位(如果目標平臺是Any CPU并且項目是應用程序類型,則生成的是32位程序集)
  • 允許不安全代碼(unsafe開關,在c#中進行指針編程,如調換a方法和b方法的地址)
  • 優化代碼(相當于csc中的/optimize,優化IL代碼讓調試難以進行,優化JIT代碼)
  • 輸出路徑(程序集輸出目錄,可選擇填寫相對路徑目錄或絕對路徑目錄)
  • XML文檔文件(相當于csc中的/doc,為程序集生成文檔注釋文件,瀏覽對方程序集對象就可以看到相關注釋,VS的智能提示技術就運用于此)
  • 為COM互操作注冊(指示托管應用程序將公開一個 COM 對象,使COM對象可以與托管應用程序進行交互)

2.在高級生成設置中有:語言版本(可以選擇C#版本)、調試信息(相當于csc中的/debug。選擇none則不生成任何調試信息,無法調試。選擇full則允許將調試器附加到運行程序,生成pdb調試文件。選擇pdb-only,自.NET2.0開始與full選項完全相同,生成相同的pdb調試文件。)、文件對齊(指定輸出文件中節的大小)、DLL基址(起點地址)

3.在生成事件選項中可以設置生成前和生產后執行的命令行,我們可以執行一些命令。

4.在調試選項中有一欄叫:啟用Visual Studio承載進程,通過在vshost.exe中加載運行項目程序集,這個選項可以增加程序的調試性能,啟用后會自動在輸出目錄生成{程序集名稱}.vshost.exe這樣一個文件,只有當當前項目不是啟動項目的時候才能刪除該文件。

IntelliTrace智能追溯

還要介紹一點VS的是,其IntelliTrace智能追溯功能,該功能最早存在于VS2010旗艦版,是我用的最舒服的一個功能。

簡單介紹,該功能是用來輔助調試的,在調試時可以讓開發人員了解并追溯代碼所產生的一些事件,并且能夠進行回溯以查看應用程序中發生的情形,它是一個非常強大的調試追蹤器,它可以捕捉由你代碼產生的事件,如異常事件、函數調用(從入口)、ADO.NET的命令(Sql查詢語句...)、ASP.NET相關事件、代碼發送的HTTP請求、程序集加載卸載事件、文件訪問打開關閉事件、Winform/Webform/WPF動作事件、線程事件、環境變量、Console/Trace等輸出...

我們可以通過在調試狀態下點擊調試菜單-窗口-顯示診斷工具,或者直接按Ctrl+Alt+F2來喚起該功能窗口。

當然,VS還有其它強大的功能,我建議大家依次點完 菜單項中的 調試、體系結構、分析這三個大菜單里面的所有項,你會發現VS真是一個強大的IDE。比較實用且方便的功能舉幾個例子:

比如 從代碼生成的序列圖,該功能在vs2015之前的版本可以找到(https://msdn.microsoft.com/en-us/library/dd409377.aspx?、https://www.zhihu.com/question/36413876)

比如 模塊關系的代碼圖,可以看到各模塊間的關系?

比如 對解決方案的代碼度量分析結果?

比如 調試狀態下 函數調用的 代碼圖,我們可以看到MVC框架的函數管道模型

以及并行堆棧情況、加載的模塊、線程的實際情況

還有如進程、內存、反匯編、寄存器等的功能,這里不再一一展示

鏈接

有關解決方案:https://msdn.microsoft.com/zh-cn/library/b142f8e7(v=vs.110).aspx 有關項目模板:?https://msdn.microsoft.com/zh-cn/library/ms247121(v=vs.110).aspx? 有關項目元素的說明介紹:https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/16satcwx(v%3dvs.100)? 有關調試更多內容:https://docs.microsoft.com/zh-cn/visualstudio/debugger/ 有關代碼設計建議:https://docs.microsoft.com/zh-cn/visualstudio/code-quality/code-analysis-for-managed-code-warnings? 有關IntelliTrace介紹:https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/dd264915(v%3dvs.100)

建議

我熱愛編程。

我知道大多數人對技術的積累都是來自于平常工作中,工作中用到的就去學,用不到就不學,學一年的知識,然后用個五六年。? 我也能理解人的理想和追求不同,有的人可能就想平淡點生活。有的人可能是過了拼勁,習慣了安逸。有的人已經認命了。? 而我現在也每天飽滿工作沒多少時間,但在下班之余我仍然堅持每天都看一看書。? 想學沒時間學,想拼不知道往哪拼。有埋汰自己腦袋笨的,有說自己不感興趣的。有明明躊躇滿志,但總三天捕魚兩天曬網的。我身邊的朋友大多都這樣。

我想說,盡管我們每個人的境遇、思想、規劃不同,但我肯定大家大部分是出于生計而工作。? 而出于生計,那就是為了自己。而既然是為了自己,那就別每天渾渾噩噩過,即使你因各種原因而沒有斗志。

編程來不得虛的,如果你沒走上管理,那么你的技術好就是好,不好就是不好,混不得,一分技術一分錢。自己不扎實,你運氣就不可能太好。 技術是相通的,操作系統、通信、數據結構、協議標準、技術規范、設計模式,語言只是門工具。要知其然也要知其所以然,只知道1個梨+1個梨=2個梨,不知道1個蘋果+1個蘋果等于啥就悲劇了。

那怎樣提升自己?肯定不能像之前那樣被動的去學習了。 光靠工作中的積累帶來的提升是沒有多少。你不能靠1年的技術重復3年的勞動,自己不想提升就不能怨天尤人。 上班大家都一樣,我認為成功與否取決于你的業余時間。你每天下班無論再苦都要花一個小時來學習,學什么都行,肯定能改變你的人生軌跡。 比如你每天下班后都用一小時來學一個概念或技術點,那么300天就是300個概念或者技術點,這是何等的恐怖。

當然,這里的學要有點小方法小技巧的。不能太一條道摸到黑的那種,雖然這樣最終也能成功,并且印象還深刻,但是總歸效率是有點低的。 比如你從網上下載個項目源碼,你項目結構不知道,該項目運用技術棧也不太了解,就一點一點的開始解讀。這是個提升的好方法,但這樣很累,可以成功,但是很慢。見的多懂的少,往往會因為一個概念上的缺失而在一個細小的問題上浪費很長時間。或者說一直漫無目的的看博客來了解技術,那樣獲取的知識也不系統。

我的建議是讀書,書分兩類,一類是 講底層概念的 一類是 講上層技術實現的。 可以先從上層技術實現的書讀起(如何連接數據庫、如何寫網頁、如何寫窗體這些)。在有一定編程經驗后就從底層概念的書開始讀,操作系統的、通信的、數據庫的、.NET相關組成的這些... 讀完之后再回過頭讀這些上層技術的書就會看的更明白更透徹,最后再琢磨git下來的項目就顯得輕松了。

就.NET CLR組成這一塊中文書籍比較少,由淺到深推薦的書有 你必須知道的.NET(挺通俗),CLR C#(挺通俗,進階必看),如果你想進一步了解CLR,可以看看園子里 包建強http://www.cnblogs.com/Jax/archive/2009/05/25/1488835.html 和中道學友http://www.cnblogs.com/awpatp/archive/2009/11/11/1601397.html翻譯的書籍及文章,當然如果你英語合格的話也可以直接閱讀他們翻譯的來源書籍,我這里有Expert .NET 2.0 IL Assembler的機器翻譯版,同時我也建議從調試的方面入手,如 NET高級調試(好多.NET文件調試、反編譯的文章都是參考這本書和Apress.Expert.dot.NET.2.0.IL.Assembler(這本書我有機器翻譯版)的內容)或者看看Java的JVM的文章。 歡迎加群和我交流(書籍我都放在群文件里了)

?

現在技術發展很快,我建議大家有基礎的可以直接看官方文檔,(詳細鏈接我已經在各小節給出)以下是部分常用總鏈接:

asp.net指南:https://docs.microsoft.com/zh-cn/aspnet/#pivot=core? Visual Studio IDE 指南:https://docs.microsoft.com/zh-cn/visualstudio/ide/? C# 指南:?https://docs.microsoft.com/zh-cn/dotnet/csharp/ .NET指南:https://docs.microsoft.com/zh-cn/dotnet/standard/? 微軟開發文檔:https://docs.microsoft.com/zh-cn/

轉載于:https://www.cnblogs.com/zy-123/p/10431866.html

總結

以上是生活随笔為你收集整理的通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 转自:https://www.cnblogs.com/1996V/p/9037603.html#net1...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

强奷人妻日本中文字幕 | 免费观看激色视频网站 | 妺妺窝人体色www在线小说 | 特级做a爰片毛片免费69 | 无码人妻丰满熟妇区毛片18 | 伦伦影院午夜理论片 | 少妇一晚三次一区二区三区 | 亚洲一区二区三区含羞草 | 国产精品理论片在线观看 | 国产精品美女久久久久av爽李琼 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 亚洲日本va中文字幕 | 97久久精品无码一区二区 | 美女极度色诱视频国产 | 精品日本一区二区三区在线观看 | 日日橹狠狠爱欧美视频 | 377p欧洲日本亚洲大胆 | 国产精品久久久久久久影院 | 久久综合给久久狠狠97色 | 少妇太爽了在线观看 | 久久综合九色综合97网 | 一本久道久久综合婷婷五月 | 免费观看激色视频网站 | 久久久久久久久蜜桃 | 扒开双腿吃奶呻吟做受视频 | 99视频精品全部免费免费观看 | 伊人色综合久久天天小片 | 三上悠亚人妻中文字幕在线 | 日韩人妻系列无码专区 | 性色av无码免费一区二区三区 | 熟妇人妻中文av无码 | 特大黑人娇小亚洲女 | 国产凸凹视频一区二区 | 国产三级久久久精品麻豆三级 | 性做久久久久久久久 | 久久99热只有频精品8 | 亚洲精品国偷拍自产在线麻豆 | 欧美老人巨大xxxx做受 | 久久久久成人片免费观看蜜芽 | 六十路熟妇乱子伦 | 精品成人av一区二区三区 | 欧美精品免费观看二区 | 无遮无挡爽爽免费视频 | 成人免费视频在线观看 | 人人妻人人澡人人爽人人精品 | 日本丰满护士爆乳xxxx | 高清无码午夜福利视频 | 无码吃奶揉捏奶头高潮视频 | 亚洲精品无码国产 | 国产高潮视频在线观看 | 久久精品99久久香蕉国产色戒 | 欧洲vodafone精品性 | 樱花草在线社区www | 国产成人一区二区三区在线观看 | 午夜精品一区二区三区在线观看 | 色综合视频一区二区三区 | 欧美国产日产一区二区 | 国产做国产爱免费视频 | 无码人妻丰满熟妇区毛片18 | 双乳奶水饱满少妇呻吟 | 精品乱子伦一区二区三区 | 国产综合在线观看 | 日本在线高清不卡免费播放 | 四虎永久在线精品免费网址 | 又大又紧又粉嫩18p少妇 | 狂野欧美性猛xxxx乱大交 | 极品尤物被啪到呻吟喷水 | 国内少妇偷人精品视频免费 | 国精产品一区二区三区 | 麻豆国产丝袜白领秘书在线观看 | 欧美xxxx黑人又粗又长 | 久久久精品人妻久久影视 | 久久久中文久久久无码 | 久久综合激激的五月天 | 丰满人妻一区二区三区免费视频 | 亚洲成av人片在线观看无码不卡 | 女高中生第一次破苞av | 精品久久久中文字幕人妻 | 国产成人综合色在线观看网站 | 三级4级全黄60分钟 | 人人妻人人藻人人爽欧美一区 | 日本又色又爽又黄的a片18禁 | 熟妇女人妻丰满少妇中文字幕 | 乱人伦人妻中文字幕无码久久网 | 一本久道高清无码视频 | 小鲜肉自慰网站xnxx | 国产精品久久久久影院嫩草 | 性生交大片免费看女人按摩摩 | 天天摸天天碰天天添 | 熟妇女人妻丰满少妇中文字幕 | 国产成人综合色在线观看网站 | 18禁止看的免费污网站 | 国产精品久久久久久无码 | 日韩人妻无码中文字幕视频 | 国产熟妇另类久久久久 | 国产九九九九九九九a片 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 东北女人啪啪对白 | 免费视频欧美无人区码 | 亚洲 日韩 欧美 成人 在线观看 | 中国大陆精品视频xxxx | 永久黄网站色视频免费直播 | 国产超级va在线观看视频 | 久久久www成人免费毛片 | 午夜精品一区二区三区的区别 | 久久99国产综合精品 | 久久人人爽人人人人片 | 亚洲小说图区综合在线 | 欧美freesex黑人又粗又大 | 人人妻人人藻人人爽欧美一区 | 日本又色又爽又黄的a片18禁 | 中文字幕无码热在线视频 | 老子影院午夜精品无码 | 美女极度色诱视频国产 | 精品国产av色一区二区深夜久久 | 日本免费一区二区三区最新 | 久久无码人妻影院 | 亚洲日本va午夜在线电影 | 九九在线中文字幕无码 | 国产亚洲tv在线观看 | аⅴ资源天堂资源库在线 | 7777奇米四色成人眼影 | 乱人伦人妻中文字幕无码久久网 | 精品人妻人人做人人爽夜夜爽 | 国产欧美精品一区二区三区 | 国内老熟妇对白xxxxhd | 377p欧洲日本亚洲大胆 | 野狼第一精品社区 | 亚洲区小说区激情区图片区 | 久久精品国产日本波多野结衣 | 性开放的女人aaa片 | 成人精品一区二区三区中文字幕 | 国产成人精品无码播放 | 毛片内射-百度 | 性做久久久久久久久 | 国产 精品 自在自线 | 精品国产国产综合精品 | 蜜桃无码一区二区三区 | 亚洲精品成a人在线观看 | 久久精品丝袜高跟鞋 | 四虎永久在线精品免费网址 | 国产高潮视频在线观看 | 99久久99久久免费精品蜜桃 | 狠狠亚洲超碰狼人久久 | 久久久久99精品国产片 | 一本大道久久东京热无码av | 欧美性黑人极品hd | 亚洲午夜无码久久 | 无码国产色欲xxxxx视频 | 亚洲小说春色综合另类 | 秋霞成人午夜鲁丝一区二区三区 | 福利一区二区三区视频在线观看 | 国产亚洲精品久久久久久大师 | 国产尤物精品视频 | 中文字幕av日韩精品一区二区 | 亚洲熟妇色xxxxx欧美老妇y | 国产sm调教视频在线观看 | 人妻有码中文字幕在线 | 久久亚洲中文字幕无码 | 国产美女极度色诱视频www | 无码任你躁久久久久久久 | 一本一道久久综合久久 | 色婷婷av一区二区三区之红樱桃 | 日本一卡二卡不卡视频查询 | 久久综合给久久狠狠97色 | 国产在线aaa片一区二区99 | 人妻无码αv中文字幕久久琪琪布 | 国产精品毛多多水多 | 国产午夜手机精彩视频 | 老子影院午夜精品无码 | 午夜理论片yy44880影院 | 中文字幕日产无线码一区 | 好爽又高潮了毛片免费下载 | 蜜桃av抽搐高潮一区二区 | 嫩b人妻精品一区二区三区 | 国产成人无码午夜视频在线观看 | 欧美人与动性行为视频 | 最新国产乱人伦偷精品免费网站 | 国产精品-区区久久久狼 | 扒开双腿疯狂进出爽爽爽视频 | 久久99精品国产麻豆 | 欧洲熟妇精品视频 | 午夜嘿嘿嘿影院 | 波多野结衣av在线观看 | 亚洲一区av无码专区在线观看 | 大色综合色综合网站 | 人妻中文无码久热丝袜 | 动漫av网站免费观看 | 国产三级久久久精品麻豆三级 | 四虎永久在线精品免费网址 | 高中生自慰www网站 | 日韩欧美群交p片內射中文 | 免费无码午夜福利片69 | 男女爱爱好爽视频免费看 | 日本乱偷人妻中文字幕 | 亚洲s码欧洲m码国产av | 久久精品国产一区二区三区肥胖 | 亚洲综合久久一区二区 | 无码精品人妻一区二区三区av | 又黄又爽又色的视频 | 好爽又高潮了毛片免费下载 | 精品国偷自产在线视频 | 亚洲成a人片在线观看无码3d | 久久久久亚洲精品男人的天堂 | 久久久久久av无码免费看大片 | 日本一区二区三区免费高清 | 欧美黑人乱大交 | 夜夜影院未满十八勿进 | 丰满人妻一区二区三区免费视频 | 久久久久久a亚洲欧洲av冫 | 色婷婷av一区二区三区之红樱桃 | 亚洲综合无码久久精品综合 | 精品 日韩 国产 欧美 视频 | 永久免费观看美女裸体的网站 | 欧美人与物videos另类 | 呦交小u女精品视频 | 丰满少妇人妻久久久久久 | 亚洲s色大片在线观看 | 乌克兰少妇xxxx做受 | 国产精品久久久av久久久 | 999久久久国产精品消防器材 | 黑森林福利视频导航 | 日本精品人妻无码免费大全 | 久久精品中文字幕大胸 | 一本久久a久久精品亚洲 | 波多野结衣av在线观看 | 国内精品人妻无码久久久影院 | 国产精品无码久久av | 99精品国产综合久久久久五月天 | 色综合久久久久综合一本到桃花网 | 漂亮人妻洗澡被公强 日日躁 | 奇米影视7777久久精品人人爽 | 国产在线精品一区二区高清不卡 | 丰满人妻一区二区三区免费视频 | 日韩精品无码一本二本三本色 | 国产深夜福利视频在线 | 又大又黄又粗又爽的免费视频 | 亚洲国产精品无码一区二区三区 | 久久久精品欧美一区二区免费 | 少妇厨房愉情理9仑片视频 | 国产成人无码区免费内射一片色欲 | 亚洲人成无码网www | 少妇厨房愉情理9仑片视频 | 丝袜 中出 制服 人妻 美腿 | 亚洲国产精品一区二区美利坚 | 国产精品无码成人午夜电影 | 久久久久国色av免费观看性色 | 少妇无套内谢久久久久 | 免费无码一区二区三区蜜桃大 | 精品午夜福利在线观看 | 中国女人内谢69xxxxxa片 | 亚洲精品成a人在线观看 | 精品无码国产一区二区三区av | 天天燥日日燥 | 欧美 亚洲 国产 另类 | 中文字幕亚洲情99在线 | 人人妻人人澡人人爽精品欧美 | 在线观看国产午夜福利片 | 未满小14洗澡无码视频网站 | 夜精品a片一区二区三区无码白浆 | 亚洲综合无码久久精品综合 | 少妇无套内谢久久久久 | 国产午夜视频在线观看 | 牲欲强的熟妇农村老妇女视频 | 97久久超碰中文字幕 | 中文字幕无线码 | 亚洲 激情 小说 另类 欧美 | 黄网在线观看免费网站 | 欧美人与禽zoz0性伦交 | 亚洲精品鲁一鲁一区二区三区 | 国产欧美精品一区二区三区 | 日本爽爽爽爽爽爽在线观看免 | 国产一区二区三区影院 | 国产欧美熟妇另类久久久 | 成人免费视频在线观看 | 四虎4hu永久免费 | 欧美第一黄网免费网站 | 妺妺窝人体色www婷婷 | 99riav国产精品视频 | 免费无码av一区二区 | 久久精品国产精品国产精品污 | 人妻尝试又大又粗久久 | 婷婷综合久久中文字幕蜜桃三电影 | 日韩亚洲欧美精品综合 | 国产乱人伦av在线无码 | 国产在热线精品视频 | 亚洲精品一区二区三区在线观看 | 亚洲色无码一区二区三区 | 亚洲爆乳精品无码一区二区三区 | 国产电影无码午夜在线播放 | 久久久久久久久蜜桃 | 亚洲欧洲日本综合aⅴ在线 | 又紧又大又爽精品一区二区 | 亚洲一区二区三区无码久久 | 免费看男女做好爽好硬视频 | 亚洲精品欧美二区三区中文字幕 | 中文字幕无码视频专区 | 国产成人综合色在线观看网站 | 老头边吃奶边弄进去呻吟 | 一本色道久久综合亚洲精品不卡 | 亚洲欧美日韩成人高清在线一区 | 蜜桃臀无码内射一区二区三区 | 国产超级va在线观看视频 | 成人精品视频一区二区三区尤物 | 国产肉丝袜在线观看 | 久久精品国产亚洲精品 | 久久99精品国产.久久久久 | 性欧美牲交xxxxx视频 | 偷窥村妇洗澡毛毛多 | 精品水蜜桃久久久久久久 | 西西人体www44rt大胆高清 | 久久久久免费看成人影片 | 成人免费视频一区二区 | 成熟女人特级毛片www免费 | 免费视频欧美无人区码 | 免费乱码人妻系列无码专区 | 精品国产乱码久久久久乱码 | 又色又爽又黄的美女裸体网站 | 亚洲啪av永久无码精品放毛片 | 欧美自拍另类欧美综合图片区 | 少妇无码一区二区二三区 | 51国偷自产一区二区三区 | 久久zyz资源站无码中文动漫 | 精品偷自拍另类在线观看 | 午夜精品久久久久久久久 | 中文字幕色婷婷在线视频 | 国产综合久久久久鬼色 | 久久午夜夜伦鲁鲁片无码免费 | 蜜臀aⅴ国产精品久久久国产老师 | 中文毛片无遮挡高清免费 | 中文字幕无码乱人伦 | 一本久道高清无码视频 | 国产片av国语在线观看 | 无码av岛国片在线播放 | 无码人妻久久一区二区三区不卡 | 国产三级精品三级男人的天堂 | 亚洲小说图区综合在线 | 亚洲精品欧美二区三区中文字幕 | 日韩精品无码一本二本三本色 | 欧美性猛交xxxx富婆 | 免费观看激色视频网站 | 丰满妇女强制高潮18xxxx | 亚无码乱人伦一区二区 | 国产精品亚洲专区无码不卡 | 欧美 丝袜 自拍 制服 另类 | 无码精品国产va在线观看dvd | 粉嫩少妇内射浓精videos | 国产精品手机免费 | 丰满少妇女裸体bbw | 亚洲精品国产精品乱码不卡 | 国产极品视觉盛宴 | 亚洲国产av美女网站 | 亚洲色成人中文字幕网站 | 国产人妖乱国产精品人妖 | 欧美精品国产综合久久 | 精品水蜜桃久久久久久久 | 最近免费中文字幕中文高清百度 | 久久精品国产日本波多野结衣 | 亚洲狠狠色丁香婷婷综合 | 欧美日韩色另类综合 | 国内精品久久毛片一区二区 | 久久99久久99精品中文字幕 | 久久久久亚洲精品男人的天堂 | 在线观看国产一区二区三区 | 亚洲成a人一区二区三区 | 国产午夜无码视频在线观看 | 久久亚洲精品中文字幕无男同 | 欧美性色19p | 国产电影无码午夜在线播放 | 久久亚洲日韩精品一区二区三区 | 亚洲国精产品一二二线 | 欧洲美熟女乱又伦 | 在线天堂新版最新版在线8 | 国产在线一区二区三区四区五区 | 国产精品久久久久久久9999 | 老熟女乱子伦 | 久久熟妇人妻午夜寂寞影院 | 日日天日日夜日日摸 | 久久精品中文字幕大胸 | 黑人粗大猛烈进出高潮视频 | 国产亚洲欧美在线专区 | 正在播放东北夫妻内射 | 久久久久久av无码免费看大片 | 国产精品国产自线拍免费软件 | 55夜色66夜色国产精品视频 | 亚洲一区二区三区四区 | 国产精品无码永久免费888 | 免费观看又污又黄的网站 | 亚洲日韩中文字幕在线播放 | 免费看男女做好爽好硬视频 | 国产亚洲日韩欧美另类第八页 | 色一情一乱一伦一区二区三欧美 | 久久人人爽人人人人片 | 夜精品a片一区二区三区无码白浆 | 国产高潮视频在线观看 | 成熟女人特级毛片www免费 | 无套内谢老熟女 | 亚洲熟悉妇女xxx妇女av | 久久精品99久久香蕉国产色戒 | √天堂中文官网8在线 | 在线观看国产一区二区三区 | 日本精品高清一区二区 | а天堂中文在线官网 | 亚洲日韩精品欧美一区二区 | 亚洲狠狠色丁香婷婷综合 | 久久精品女人天堂av免费观看 | 国产精品亚洲五月天高清 | 亚洲成在人网站无码天堂 | 久久久久久国产精品无码下载 | 亚洲a无码综合a国产av中文 | 国产日产欧产精品精品app | 综合人妻久久一区二区精品 | 日本精品少妇一区二区三区 | 偷窥村妇洗澡毛毛多 | 自拍偷自拍亚洲精品被多人伦好爽 | 色窝窝无码一区二区三区色欲 | 精品无码成人片一区二区98 | 在教室伦流澡到高潮hnp视频 | 精品久久久久久人妻无码中文字幕 | 久久精品视频在线看15 | 狂野欧美激情性xxxx | 精品无人国产偷自产在线 | 亚洲熟妇色xxxxx欧美老妇y | 国产激情一区二区三区 | 正在播放老肥熟妇露脸 | 欧美激情内射喷水高潮 | 国产精品久久久av久久久 | 国产莉萝无码av在线播放 | 好爽又高潮了毛片免费下载 | 国产精品无码久久av | 中文字幕乱妇无码av在线 | 亚洲欧美日韩成人高清在线一区 | 女人和拘做爰正片视频 | 西西人体www44rt大胆高清 | 精品厕所偷拍各类美女tp嘘嘘 | 男女超爽视频免费播放 | 国产激情综合五月久久 | 综合网日日天干夜夜久久 | 国产情侣作爱视频免费观看 | 久久久久99精品国产片 | 青草青草久热国产精品 | 国产高潮视频在线观看 | 奇米影视888欧美在线观看 | √8天堂资源地址中文在线 | 国产精品久久久久久无码 | 99久久久无码国产精品免费 | 秋霞特色aa大片 | 99久久亚洲精品无码毛片 | 国产精品久免费的黄网站 | 亚洲成色www久久网站 | 日日鲁鲁鲁夜夜爽爽狠狠 | 亚洲欧洲日本综合aⅴ在线 | 男女作爱免费网站 | 欧美三级不卡在线观看 | 久久久久久av无码免费看大片 | 国产超级va在线观看视频 | 老熟女重囗味hdxx69 | 水蜜桃av无码 | 男女下面进入的视频免费午夜 | 人妻少妇被猛烈进入中文字幕 | 性色av无码免费一区二区三区 | 国产精品欧美成人 | 日本乱人伦片中文三区 | 狠狠色噜噜狠狠狠狠7777米奇 | 国产在热线精品视频 | 特黄特色大片免费播放器图片 | 日本www一道久久久免费榴莲 | 色五月丁香五月综合五月 | 国产97人人超碰caoprom | 精品午夜福利在线观看 | 亚洲精品中文字幕久久久久 | 白嫩日本少妇做爰 | 精品无码国产自产拍在线观看蜜 | 欧美 丝袜 自拍 制服 另类 | 兔费看少妇性l交大片免费 | 国产电影无码午夜在线播放 | 久久婷婷五月综合色国产香蕉 | 精品偷自拍另类在线观看 | 国产精品高潮呻吟av久久 | 国产欧美亚洲精品a | 日本在线高清不卡免费播放 | 性生交片免费无码看人 | 丝袜人妻一区二区三区 | 精品乱子伦一区二区三区 | 国产午夜无码视频在线观看 | 国产乱码精品一品二品 | 久久久久久av无码免费看大片 | 久久精品视频在线看15 | 三上悠亚人妻中文字幕在线 | 丰满岳乱妇在线观看中字无码 | 丁香啪啪综合成人亚洲 | 日韩精品久久久肉伦网站 | 久久国产精品萌白酱免费 | 国产三级精品三级男人的天堂 | 秋霞特色aa大片 | 高潮喷水的毛片 | 亚洲欧美国产精品久久 | 男人的天堂av网站 | 亚洲人交乣女bbw | 亚洲国产av美女网站 | 玩弄人妻少妇500系列视频 | 高清无码午夜福利视频 | v一区无码内射国产 | 理论片87福利理论电影 | 国内少妇偷人精品视频 | 久久久久久av无码免费看大片 | 国产精品国产三级国产专播 | 欧美肥老太牲交大战 | 久久 国产 尿 小便 嘘嘘 | 亚洲成av人影院在线观看 | 无遮无挡爽爽免费视频 | 丰满肥臀大屁股熟妇激情视频 | 久激情内射婷内射蜜桃人妖 | 性色av无码免费一区二区三区 | 日本在线高清不卡免费播放 | 久久久久成人精品免费播放动漫 | 国产国产精品人在线视 | 2019nv天堂香蕉在线观看 | 国内精品一区二区三区不卡 | 日本一区二区三区免费播放 | 国产精品久免费的黄网站 | 高潮喷水的毛片 | 久久久久99精品国产片 | 亚拍精品一区二区三区探花 | 亚洲日韩乱码中文无码蜜桃臀网站 | 亚洲欧美日韩成人高清在线一区 | 婷婷色婷婷开心五月四房播播 | 高清无码午夜福利视频 | 成人aaa片一区国产精品 | 亚洲乱码中文字幕在线 | 国产精品久久久午夜夜伦鲁鲁 | 国产内射老熟女aaaa | 日本一区二区更新不卡 | 亚洲成a人片在线观看无码3d | 亚洲精品久久久久avwww潮水 | 国产在线精品一区二区高清不卡 | 免费男性肉肉影院 | 亚洲天堂2017无码 | 在线看片无码永久免费视频 | 黑人巨大精品欧美黑寡妇 | 日本成熟视频免费视频 | 国产黑色丝袜在线播放 | 男人和女人高潮免费网站 | 国产手机在线αⅴ片无码观看 | 搡女人真爽免费视频大全 | 77777熟女视频在线观看 а天堂中文在线官网 | 亚洲日韩一区二区 | 中文字幕久久久久人妻 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 免费国产黄网站在线观看 | 国产美女极度色诱视频www | 国产精品高潮呻吟av久久4虎 | 欧美午夜特黄aaaaaa片 | 国产亚洲日韩欧美另类第八页 | 欧美性色19p | 动漫av一区二区在线观看 | 欧美日韩亚洲国产精品 | 国产人妻精品午夜福利免费 | 一本色道婷婷久久欧美 | 久久亚洲中文字幕无码 | 色综合久久久久综合一本到桃花网 | a国产一区二区免费入口 | 好爽又高潮了毛片免费下载 | 日本熟妇大屁股人妻 | 国产人妻人伦精品 | 亚洲国产欧美国产综合一区 | 精品乱子伦一区二区三区 | 人人澡人人妻人人爽人人蜜桃 | 亚洲日本va中文字幕 | 亚洲成熟女人毛毛耸耸多 | 少妇无码av无码专区在线观看 | 国产精品嫩草久久久久 | 国产午夜精品一区二区三区嫩草 | 97精品国产97久久久久久免费 | a片在线免费观看 | 欧美日韩久久久精品a片 | 国产精品久久久久9999小说 | 精品国产乱码久久久久乱码 | 亚洲一区二区三区无码久久 | 高潮毛片无遮挡高清免费视频 | 狂野欧美性猛交免费视频 | 欧美野外疯狂做受xxxx高潮 | 美女极度色诱视频国产 | 国产suv精品一区二区五 | 学生妹亚洲一区二区 | 久久 国产 尿 小便 嘘嘘 | 乱码午夜-极国产极内射 | 蜜臀av无码人妻精品 | 内射白嫩少妇超碰 | 亚洲欧美精品伊人久久 | 欧美丰满熟妇xxxx性ppx人交 | 99精品久久毛片a片 | 无码免费一区二区三区 | 久久97精品久久久久久久不卡 | 久久精品99久久香蕉国产色戒 | 欧美高清在线精品一区 | 国产乱子伦视频在线播放 | 自拍偷自拍亚洲精品被多人伦好爽 | 成人免费视频视频在线观看 免费 | 老司机亚洲精品影院无码 | а天堂中文在线官网 | 无遮无挡爽爽免费视频 | 国产精品无码一区二区三区不卡 | 大肉大捧一进一出好爽视频 | 国产成人无码专区 | 久久综合香蕉国产蜜臀av | 人人超人人超碰超国产 | 国产免费无码一区二区视频 | 亚洲自偷精品视频自拍 | 美女张开腿让人桶 | 窝窝午夜理论片影院 | 亚洲人成人无码网www国产 | 少妇一晚三次一区二区三区 | 麻豆av传媒蜜桃天美传媒 | 色欲av亚洲一区无码少妇 | 久久99精品久久久久久动态图 | 美女极度色诱视频国产 | 领导边摸边吃奶边做爽在线观看 | 亚洲呦女专区 | 成在人线av无码免费 | 蜜桃无码一区二区三区 | www国产亚洲精品久久网站 | 中文字幕无码日韩欧毛 | 露脸叫床粗话东北少妇 | 国产精品亚洲专区无码不卡 | 亚洲精品国产a久久久久久 | 国产精品成人av在线观看 | 成人免费视频视频在线观看 免费 | 国产精品沙发午睡系列 | 粗大的内捧猛烈进出视频 | 在线观看国产一区二区三区 | 免费网站看v片在线18禁无码 | 亚洲成a人片在线观看无码3d | av在线亚洲欧洲日产一区二区 | 久久久久免费看成人影片 | 领导边摸边吃奶边做爽在线观看 | 波多野结衣一区二区三区av免费 | 国产国语老龄妇女a片 | 欧美激情综合亚洲一二区 | 国产特级毛片aaaaaaa高清 | 日韩无套无码精品 | 久久久精品欧美一区二区免费 | 国精产品一区二区三区 | 亚洲男女内射在线播放 | 日韩人妻少妇一区二区三区 | 久久久久成人片免费观看蜜芽 | 人人澡人人妻人人爽人人蜜桃 | 人人妻人人澡人人爽欧美一区九九 | 东北女人啪啪对白 | 无码av免费一区二区三区试看 | 亚洲一区二区三区偷拍女厕 | 国产精品99久久精品爆乳 | 亚洲の无码国产の无码步美 | 成人试看120秒体验区 | 人人澡人人妻人人爽人人蜜桃 | 蜜臀av无码人妻精品 | 欧美精品国产综合久久 | 国产精品美女久久久久av爽李琼 | 无码人妻少妇伦在线电影 | av香港经典三级级 在线 | 国产精品.xx视频.xxtv | 天堂在线观看www | 欧美高清在线精品一区 | 国产精品久久国产三级国 | 精品偷拍一区二区三区在线看 | 牲欲强的熟妇农村老妇女 | 18禁止看的免费污网站 | 5858s亚洲色大成网站www | 国产精品久久久av久久久 | 国产午夜视频在线观看 | 黑人巨大精品欧美一区二区 | 帮老师解开蕾丝奶罩吸乳网站 | 狠狠综合久久久久综合网 | 激情人妻另类人妻伦 | 久久久精品456亚洲影院 | 亚洲日韩一区二区三区 | 天天av天天av天天透 | 亚洲精品鲁一鲁一区二区三区 | 99精品无人区乱码1区2区3区 | 在线观看免费人成视频 | 领导边摸边吃奶边做爽在线观看 | 亚洲の无码国产の无码步美 | 亚洲色欲色欲欲www在线 | 亚洲一区二区三区无码久久 | 国产手机在线αⅴ片无码观看 | 夜夜影院未满十八勿进 | 国产综合色产在线精品 | 亚洲国产精品美女久久久久 | 亚洲一区二区三区播放 | 特级做a爰片毛片免费69 | 亚洲色无码一区二区三区 | 久久国产精品偷任你爽任你 | 国产在线精品一区二区高清不卡 | 国产在线精品一区二区三区直播 | 97精品人妻一区二区三区香蕉 | 国内精品一区二区三区不卡 | 99久久无码一区人妻 | 麻豆国产丝袜白领秘书在线观看 | 夜夜夜高潮夜夜爽夜夜爰爰 | 丰满少妇人妻久久久久久 | 国模大胆一区二区三区 | 中文字幕乱码亚洲无线三区 | 精品久久久无码人妻字幂 | av小次郎收藏 | 国产色精品久久人妻 | 俺去俺来也在线www色官网 | 欧美 亚洲 国产 另类 | 亚洲中文字幕无码中字 | 亚洲熟妇色xxxxx亚洲 | 少妇被黑人到高潮喷出白浆 | 少妇厨房愉情理9仑片视频 | 欧美日韩在线亚洲综合国产人 | 老熟女重囗味hdxx69 | 青青青爽视频在线观看 | 国产69精品久久久久app下载 | 亚洲另类伦春色综合小说 | 最新国产乱人伦偷精品免费网站 | 天堂а√在线地址中文在线 | 国产成人无码av在线影院 | 国产av一区二区精品久久凹凸 | 午夜精品久久久久久久久 | 美女扒开屁股让男人桶 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 久久久久久av无码免费看大片 | 久久久久久久久蜜桃 | 欧美日韩人成综合在线播放 | 精品无码国产自产拍在线观看蜜 | 国产精品18久久久久久麻辣 | 性做久久久久久久免费看 | 丰满少妇高潮惨叫视频 | 国産精品久久久久久久 | 国产97人人超碰caoprom | 日韩精品无码免费一区二区三区 | 99久久久国产精品无码免费 | 欧美放荡的少妇 | av无码电影一区二区三区 | 青青青爽视频在线观看 | 久久综合给久久狠狠97色 | 欧美 丝袜 自拍 制服 另类 | 亚洲va欧美va天堂v国产综合 | 精品国产福利一区二区 | 欧美zoozzooz性欧美 | 国内精品久久毛片一区二区 | 亚洲欧美日韩成人高清在线一区 | 久久久www成人免费毛片 | 日韩人妻无码一区二区三区久久99 | 国产一区二区不卡老阿姨 | 永久免费观看美女裸体的网站 | 天堂亚洲2017在线观看 | 免费观看又污又黄的网站 | 1000部啪啪未满十八勿入下载 | 丰满人妻一区二区三区免费视频 | 成人欧美一区二区三区黑人免费 | 久久久精品人妻久久影视 | 国产精品无码永久免费888 | 久久综合激激的五月天 | 成人性做爰aaa片免费看不忠 | 欧美日本免费一区二区三区 | 人妻少妇精品无码专区二区 | 日本大乳高潮视频在线观看 | 久久久亚洲欧洲日产国码αv | 国产精品久久福利网站 | 亚洲の无码国产の无码影院 | 国产激情无码一区二区 | 欧美怡红院免费全部视频 | 亚洲成av人影院在线观看 | √天堂资源地址中文在线 | 亚洲性无码av中文字幕 | 亚洲乱码中文字幕在线 | 漂亮人妻洗澡被公强 日日躁 | 亚洲精品国产a久久久久久 | 人人澡人摸人人添 | 中文字幕色婷婷在线视频 | 久在线观看福利视频 | 老太婆性杂交欧美肥老太 | 熟女体下毛毛黑森林 | 国产69精品久久久久app下载 | av人摸人人人澡人人超碰下载 | 性做久久久久久久免费看 | 久久精品99久久香蕉国产色戒 | 久久国产劲爆∧v内射 | 呦交小u女精品视频 | 国产97色在线 | 免 | 无码成人精品区在线观看 | 无码av岛国片在线播放 | 国产精品无码一区二区桃花视频 | 午夜福利电影 | 国产免费久久久久久无码 | 一个人看的www免费视频在线观看 | 水蜜桃亚洲一二三四在线 | 夜夜躁日日躁狠狠久久av | 亚洲中文字幕在线无码一区二区 | 久久久久免费看成人影片 | 又大又紧又粉嫩18p少妇 | 呦交小u女精品视频 | 国产精品福利视频导航 | 在线播放免费人成毛片乱码 | 国产午夜亚洲精品不卡 | 国产精品国产自线拍免费软件 | 日日噜噜噜噜夜夜爽亚洲精品 | 疯狂三人交性欧美 | 久久人人爽人人爽人人片av高清 | 亚洲gv猛男gv无码男同 | 麻豆av传媒蜜桃天美传媒 | 国产人妻精品一区二区三区 | 国内少妇偷人精品视频免费 | 欧美性猛交内射兽交老熟妇 | 国产精品-区区久久久狼 | 在线播放亚洲第一字幕 | 午夜时刻免费入口 | 国产在线一区二区三区四区五区 | 精品无码国产自产拍在线观看蜜 | 亚洲自偷精品视频自拍 | 亚洲中文字幕无码中字 | 一个人看的视频www在线 | 国产精品亚洲一区二区三区喷水 | 无码国产色欲xxxxx视频 | 98国产精品综合一区二区三区 | 宝宝好涨水快流出来免费视频 | 好爽又高潮了毛片免费下载 | 亚洲国产欧美国产综合一区 | 内射老妇bbwx0c0ck | 伊人色综合久久天天小片 | 国产在热线精品视频 | 亚洲综合无码久久精品综合 | 国产精品美女久久久 | 99久久精品无码一区二区毛片 | 四虎国产精品免费久久 | 爽爽影院免费观看 | 国模大胆一区二区三区 | a在线亚洲男人的天堂 | 亚洲中文字幕乱码av波多ji | 国产亚av手机在线观看 | 日本肉体xxxx裸交 | 性生交片免费无码看人 | 日韩精品无码一区二区中文字幕 | 久久久精品国产sm最大网站 | 大肉大捧一进一出好爽视频 | 欧美放荡的少妇 | 亚洲精品一区国产 | 中文字幕无线码免费人妻 | 性欧美疯狂xxxxbbbb | 欧美丰满老熟妇xxxxx性 | 亚洲成a人一区二区三区 | 国产内射爽爽大片视频社区在线 | 少妇性l交大片 | 无码人妻av免费一区二区三区 | 亚洲精品中文字幕乱码 | 国产精品久久久久久久9999 | 伊人久久大香线焦av综合影院 | 日韩欧美群交p片內射中文 | 少妇被黑人到高潮喷出白浆 | 亚洲成在人网站无码天堂 | 日韩精品一区二区av在线 | 天下第一社区视频www日本 | 乱码午夜-极国产极内射 | 亚洲日韩av一区二区三区四区 | 少妇久久久久久人妻无码 | 欧美丰满熟妇xxxx | 国产97色在线 | 免 | 人妻少妇精品无码专区二区 | 精品少妇爆乳无码av无码专区 | 18精品久久久无码午夜福利 | 亚洲欧美色中文字幕在线 | √8天堂资源地址中文在线 | 中文字幕乱码中文乱码51精品 | 亚洲日韩av一区二区三区四区 | 性欧美熟妇videofreesex | 色综合久久久无码网中文 | 国产真实夫妇视频 | 玩弄中年熟妇正在播放 | 亚洲爆乳精品无码一区二区三区 | 日韩亚洲欧美精品综合 | 亚洲码国产精品高潮在线 | 水蜜桃色314在线观看 | 国产区女主播在线观看 | 免费人成网站视频在线观看 | 亚洲精品久久久久中文第一幕 | 国产一区二区三区四区五区加勒比 | 国产精品理论片在线观看 | 日韩亚洲欧美精品综合 | 国产在线无码精品电影网 | 国产人妻精品一区二区三区不卡 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 久久久久久久久蜜桃 | av香港经典三级级 在线 | 亚洲aⅴ无码成人网站国产app | 2019nv天堂香蕉在线观看 | 少妇邻居内射在线 | 人人妻人人藻人人爽欧美一区 | 国产亚洲美女精品久久久2020 | 免费视频欧美无人区码 | 亚洲日韩一区二区三区 | 精品久久久久久亚洲精品 | 久久综合给合久久狠狠狠97色 | 狠狠cao日日穞夜夜穞av | 在线观看国产一区二区三区 | 东京热男人av天堂 | 131美女爱做视频 | 国产成人综合美国十次 | 国产va免费精品观看 | 日韩人妻无码中文字幕视频 | 亚洲乱码日产精品bd | 国产精品美女久久久久av爽李琼 | 狠狠综合久久久久综合网 | 日本一本二本三区免费 | 久久熟妇人妻午夜寂寞影院 | 丁香花在线影院观看在线播放 | 在线视频网站www色 | 亚洲s色大片在线观看 | 久久久久亚洲精品男人的天堂 | 国产精品久久久久久久影院 | 亚洲一区二区三区四区 | 红桃av一区二区三区在线无码av | 国产午夜福利亚洲第一 | 色综合久久中文娱乐网 | 国产亲子乱弄免费视频 | 成年女人永久免费看片 | 国产亚洲视频中文字幕97精品 | 中文无码成人免费视频在线观看 | 熟女少妇在线视频播放 | 成熟妇人a片免费看网站 | 久久亚洲精品成人无码 | 久久综合激激的五月天 | 亚洲欧洲无卡二区视頻 | 亚洲国产精品毛片av不卡在线 | 欧洲欧美人成视频在线 | 亚洲男人av香蕉爽爽爽爽 | 精品成在人线av无码免费看 | 国产在线精品一区二区三区直播 | 亚洲一区二区三区四区 | 久久这里只有精品视频9 | 成 人 网 站国产免费观看 | 精品乱子伦一区二区三区 | 午夜精品久久久内射近拍高清 | 久久久无码中文字幕久... | 欧美黑人性暴力猛交喷水 | 久久99久久99精品中文字幕 | 欧美精品在线观看 | av香港经典三级级 在线 | 成人性做爰aaa片免费看不忠 | 中文无码精品a∨在线观看不卡 | 日本一卡2卡3卡四卡精品网站 | 天堂在线观看www | 日韩精品成人一区二区三区 | 成 人影片 免费观看 | 精品一区二区三区波多野结衣 | 激情爆乳一区二区三区 | 无码一区二区三区在线观看 | 国产av一区二区精品久久凹凸 | 樱花草在线社区www | 日韩欧美中文字幕公布 | 中文毛片无遮挡高清免费 | av在线亚洲欧洲日产一区二区 | 初尝人妻少妇中文字幕 | 熟妇人妻激情偷爽文 | 国产明星裸体无码xxxx视频 | 久久亚洲精品成人无码 | 激情爆乳一区二区三区 | 亚洲色欲色欲天天天www | 精品国产av色一区二区深夜久久 | 性欧美牲交在线视频 | 成人性做爰aaa片免费看不忠 | 欧美 日韩 亚洲 在线 | 无码人妻久久一区二区三区不卡 | 亚洲色大成网站www | 午夜福利试看120秒体验区 | 永久黄网站色视频免费直播 | 色噜噜亚洲男人的天堂 | 亚洲色欲久久久综合网东京热 | 欧美日韩综合一区二区三区 | 成人性做爰aaa片免费看不忠 | 少妇性荡欲午夜性开放视频剧场 | 高潮毛片无遮挡高清免费 | 久久久久国色av免费观看性色 | 真人与拘做受免费视频 | 国产精品视频免费播放 | 中文字幕乱码亚洲无线三区 | 婷婷色婷婷开心五月四房播播 | 国产情侣作爱视频免费观看 | 国产精品久久久久7777 | 亚洲爆乳精品无码一区二区三区 | 呦交小u女精品视频 | 女人被爽到呻吟gif动态图视看 | 国产激情艳情在线看视频 | 婷婷丁香五月天综合东京热 | 超碰97人人做人人爱少妇 | 亚洲综合无码一区二区三区 | 国产真实伦对白全集 | 最新版天堂资源中文官网 | 国产做国产爱免费视频 | 无码人妻丰满熟妇区毛片18 | 99久久婷婷国产综合精品青草免费 | 99久久人妻精品免费二区 | 理论片87福利理论电影 | 亚洲精品一区二区三区四区五区 | 成人毛片一区二区 | 乱码av麻豆丝袜熟女系列 | 国产免费观看黄av片 | 精品乱子伦一区二区三区 | 国内少妇偷人精品视频 | 国产97色在线 | 免 | 夜精品a片一区二区三区无码白浆 | 麻豆国产人妻欲求不满谁演的 | 亚洲欧美日韩国产精品一区二区 | 国产精品久久久久久无码 | 欧美性猛交xxxx富婆 | 久久久久亚洲精品中文字幕 | 日韩av无码一区二区三区 | 少妇无码一区二区二三区 | 免费观看黄网站 | 人人妻人人澡人人爽人人精品浪潮 | 亚洲人成无码网www | 欧美精品无码一区二区三区 | 啦啦啦www在线观看免费视频 | 无码精品人妻一区二区三区av | 亚洲精品一区二区三区大桥未久 | 奇米影视7777久久精品人人爽 | 亚洲中文字幕在线无码一区二区 | 帮老师解开蕾丝奶罩吸乳网站 | 国产婷婷色一区二区三区在线 | 精品国产乱码久久久久乱码 | 国内老熟妇对白xxxxhd | 国产精品亚洲专区无码不卡 | 国产一精品一av一免费 | 国产三级久久久精品麻豆三级 | 无套内谢老熟女 | 精品久久久无码人妻字幂 | 久久精品国产日本波多野结衣 | 久久精品视频在线看15 | 香港三级日本三级妇三级 | 色狠狠av一区二区三区 | 丰满护士巨好爽好大乳 | 亚洲国精产品一二二线 | 人妻与老人中文字幕 | 丝袜人妻一区二区三区 | 性生交大片免费看l | 图片区 小说区 区 亚洲五月 | 人妻互换免费中文字幕 | 白嫩日本少妇做爰 | av无码久久久久不卡免费网站 | 日日躁夜夜躁狠狠躁 | 国产偷自视频区视频 | 亚洲小说春色综合另类 | 午夜福利不卡在线视频 | 亚洲自偷自拍另类第1页 | 欧洲美熟女乱又伦 | 秋霞成人午夜鲁丝一区二区三区 | 国产精品无码一区二区桃花视频 | 免费乱码人妻系列无码专区 | 亚洲a无码综合a国产av中文 | 在线观看免费人成视频 | 日本va欧美va欧美va精品 | 国产综合在线观看 | 亚洲第一网站男人都懂 | 午夜男女很黄的视频 | 久久精品国产一区二区三区 | 欧美猛少妇色xxxxx | 欧美老妇与禽交 | 日韩av无码一区二区三区不卡 | 十八禁视频网站在线观看 | 天堂在线观看www | 久久国产36精品色熟妇 | 午夜不卡av免费 一本久久a久久精品vr综合 | 成人无码精品1区2区3区免费看 | 亚洲人亚洲人成电影网站色 | 麻豆国产人妻欲求不满谁演的 | 国产疯狂伦交大片 | 曰韩少妇内射免费播放 | 欧美35页视频在线观看 | 欧美人与善在线com | 99精品久久毛片a片 | 奇米影视7777久久精品人人爽 | 免费网站看v片在线18禁无码 | 日本一卡2卡3卡四卡精品网站 | 国产婷婷色一区二区三区在线 | 大肉大捧一进一出好爽视频 | 久久精品99久久香蕉国产色戒 | 亚洲国产一区二区三区在线观看 | 宝宝好涨水快流出来免费视频 | 在线a亚洲视频播放在线观看 | 精品国产av色一区二区深夜久久 | 国产精品久久久午夜夜伦鲁鲁 | 国产香蕉尹人视频在线 | 免费播放一区二区三区 | 天天摸天天透天天添 | 人人妻人人澡人人爽人人精品浪潮 | 亚洲精品一区二区三区在线观看 | 亚洲熟妇色xxxxx亚洲 | 激情综合激情五月俺也去 | 高清无码午夜福利视频 | 无码av最新清无码专区吞精 | 日韩 欧美 动漫 国产 制服 | 国产sm调教视频在线观看 | 国产午夜福利亚洲第一 | 2019午夜福利不卡片在线 | 亚洲啪av永久无码精品放毛片 | 少妇性l交大片欧洲热妇乱xxx | 国产乱子伦视频在线播放 | 中文字幕乱码人妻无码久久 | 精品成在人线av无码免费看 | 波多野结衣av一区二区全免费观看 | 色欲久久久天天天综合网精品 | 欧美丰满熟妇xxxx性ppx人交 | 中国大陆精品视频xxxx | 久久综合给合久久狠狠狠97色 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产精品办公室沙发 | 亚洲色偷偷男人的天堂 | 中文字幕亚洲情99在线 | 欧美日韩亚洲国产精品 | 国产色xx群视频射精 | 午夜福利试看120秒体验区 | 少妇被黑人到高潮喷出白浆 | 人人妻人人澡人人爽人人精品浪潮 | 免费看男女做好爽好硬视频 | 亚洲欧美日韩国产精品一区二区 | 成熟妇人a片免费看网站 | 亚洲人亚洲人成电影网站色 | 色老头在线一区二区三区 | 日韩精品a片一区二区三区妖精 | 国产精品无码久久av | 1000部夫妻午夜免费 | 欧美老熟妇乱xxxxx | 亚洲国产精品一区二区第一页 | 午夜精品久久久内射近拍高清 | 国产偷抇久久精品a片69 | 亚洲 欧美 激情 小说 另类 | 牲交欧美兽交欧美 | 欧美日韩一区二区三区自拍 | 欧美精品一区二区精品久久 | 亚洲国产精品一区二区美利坚 | 日本高清一区免费中文视频 | 综合人妻久久一区二区精品 | 久久久国产精品无码免费专区 | 欧美xxxxx精品 | 日韩亚洲欧美中文高清在线 | 在线 国产 欧美 亚洲 天堂 | 无码福利日韩神码福利片 | 色综合久久网 | 亚洲国产精品久久人人爱 | 在线播放免费人成毛片乱码 | 蜜桃无码一区二区三区 | 欧美日韩一区二区综合 | 亚洲欧美精品aaaaaa片 | 久久精品国产亚洲精品 | 人妻与老人中文字幕 | 日本精品高清一区二区 | 日韩av无码一区二区三区 | 亚洲七七久久桃花影院 | 国内精品久久毛片一区二区 | 装睡被陌生人摸出水好爽 | 亚洲精品国产a久久久久久 | 黄网在线观看免费网站 | 亚洲成av人在线观看网址 | 最近免费中文字幕中文高清百度 | 亚洲中文字幕无码一久久区 | 亚洲精品午夜无码电影网 | 亚洲一区二区三区播放 | 午夜精品久久久久久久 | 东京无码熟妇人妻av在线网址 | 日本免费一区二区三区最新 | 国产极品视觉盛宴 | 国产精品对白交换视频 | 色五月五月丁香亚洲综合网 | 国产绳艺sm调教室论坛 | 国产69精品久久久久app下载 | 国产精品美女久久久久av爽李琼 | 日韩 欧美 动漫 国产 制服 | 荡女精品导航 | 亚洲一区二区观看播放 | 亚洲爆乳精品无码一区二区三区 | 亚洲色偷偷偷综合网 | 在线天堂新版最新版在线8 | 中国女人内谢69xxxx | 久久人人97超碰a片精品 | 西西人体www44rt大胆高清 | 亚洲国产精品久久久天堂 | 无码人妻丰满熟妇区毛片18 | 国产乱子伦视频在线播放 | 女人被男人爽到呻吟的视频 | 黑人粗大猛烈进出高潮视频 | 欧美国产亚洲日韩在线二区 | 国产av剧情md精品麻豆 | 天天拍夜夜添久久精品 | 亚洲熟妇色xxxxx亚洲 | 帮老师解开蕾丝奶罩吸乳网站 | 丰腴饱满的极品熟妇 | 亚洲精品无码人妻无码 | 天堂无码人妻精品一区二区三区 | 无码中文字幕色专区 | 三级4级全黄60分钟 | 最新国产乱人伦偷精品免费网站 | 日产精品高潮呻吟av久久 | 性生交大片免费看女人按摩摩 | 亚洲中文无码av永久不收费 | 天天综合网天天综合色 | 国产午夜精品一区二区三区嫩草 | ass日本丰满熟妇pics | 色婷婷久久一区二区三区麻豆 | 国产精品理论片在线观看 | 人人妻人人澡人人爽欧美一区 | 999久久久国产精品消防器材 | 亚洲精品久久久久久一区二区 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 欧美喷潮久久久xxxxx | 久久午夜无码鲁丝片 | 欧美兽交xxxx×视频 | 激情五月综合色婷婷一区二区 | 色窝窝无码一区二区三区色欲 | 日本熟妇大屁股人妻 | 欧美丰满熟妇xxxx | 又湿又紧又大又爽a视频国产 | 日韩精品无码一区二区中文字幕 | 成在人线av无码免观看麻豆 | 图片区 小说区 区 亚洲五月 | 久久天天躁夜夜躁狠狠 | 国产精品久久久av久久久 | 高清无码午夜福利视频 | 人人妻人人澡人人爽欧美一区 | 国产精品无码永久免费888 | 无套内谢老熟女 | 国产两女互慰高潮视频在线观看 | 国产在线aaa片一区二区99 | 中文字幕乱码人妻二区三区 | 亚洲日韩一区二区 | 特大黑人娇小亚洲女 | 2020最新国产自产精品 | 亚洲欧美色中文字幕在线 | 人人妻人人澡人人爽欧美一区 | 国产内射爽爽大片视频社区在线 | 无码毛片视频一区二区本码 | 老熟妇仑乱视频一区二区 | 97久久国产亚洲精品超碰热 | 亚洲综合无码一区二区三区 | 波多野结衣乳巨码无在线观看 | 丰满人妻翻云覆雨呻吟视频 | 精品国偷自产在线 | 内射巨臀欧美在线视频 | 国产成人综合美国十次 | 久久99精品久久久久久 | 精品亚洲韩国一区二区三区 | 欧美 亚洲 国产 另类 | 久久精品国产日本波多野结衣 | 国产乱人伦偷精品视频 | 精品国产国产综合精品 | 一本大道伊人av久久综合 | 亚洲色www成人永久网址 | 国产偷自视频区视频 | 中文字幕av伊人av无码av | 人妻少妇被猛烈进入中文字幕 | 久久精品国产99精品亚洲 | 亚洲色大成网站www | 欧美人与物videos另类 | 亚洲成a人片在线观看日本 | 无码人妻精品一区二区三区不卡 | 亚洲精品中文字幕乱码 | 人人爽人人澡人人人妻 | 国产免费观看黄av片 | 亚洲va欧美va天堂v国产综合 | 亚洲欧美精品伊人久久 | 亚洲欧洲日本综合aⅴ在线 | 中文字幕无码av波多野吉衣 | 成人影院yy111111在线观看 | 澳门永久av免费网站 | 97人妻精品一区二区三区 | 伊在人天堂亚洲香蕉精品区 | 人妻插b视频一区二区三区 | 国产xxx69麻豆国语对白 | 亚洲精品一区三区三区在线观看 | 国产亚洲美女精品久久久2020 | 国产精品久久久午夜夜伦鲁鲁 | 日本成熟视频免费视频 | 国产一区二区不卡老阿姨 | 黄网在线观看免费网站 | 在线看片无码永久免费视频 | аⅴ资源天堂资源库在线 | 又色又爽又黄的美女裸体网站 | 99在线 | 亚洲 | 久精品国产欧美亚洲色aⅴ大片 | 亚洲国产欧美日韩精品一区二区三区 | 亚洲男女内射在线播放 | 无码成人精品区在线观看 | 国产成人一区二区三区在线观看 | √天堂中文官网8在线 | 午夜无码人妻av大片色欲 | 人妻有码中文字幕在线 | 日韩av激情在线观看 | 大乳丰满人妻中文字幕日本 | 一本色道久久综合狠狠躁 | 熟妇女人妻丰满少妇中文字幕 | 欧美大屁股xxxxhd黑色 | 少妇的肉体aa片免费 | 精品无码一区二区三区爱欲 | 亚洲大尺度无码无码专区 | 国产精品无码一区二区桃花视频 | 日韩成人一区二区三区在线观看 | 久久99精品久久久久久动态图 | 在线精品国产一区二区三区 | 国产成人精品无码播放 | 又粗又大又硬又长又爽 | 久久午夜无码鲁丝片午夜精品 | 亚洲精品久久久久中文第一幕 | 欧美日韩视频无码一区二区三 | 精品国产乱码久久久久乱码 | 国产亚洲精品精品国产亚洲综合 | 乱码午夜-极国产极内射 | 久久久久久久人妻无码中文字幕爆 | 特大黑人娇小亚洲女 | 精品国产乱码久久久久乱码 | 十八禁真人啪啪免费网站 | 国产亚av手机在线观看 | 娇妻被黑人粗大高潮白浆 | 亚洲精品鲁一鲁一区二区三区 | 免费无码一区二区三区蜜桃大 | 国产三级久久久精品麻豆三级 | 国产另类ts人妖一区二区 | 欧美熟妇另类久久久久久多毛 | 国内精品人妻无码久久久影院蜜桃 | 久久亚洲精品中文字幕无男同 | 少妇的肉体aa片免费 | 熟女体下毛毛黑森林 | 波多野结衣aⅴ在线 | 亚洲欧美日韩国产精品一区二区 | 欧美熟妇另类久久久久久不卡 | 日韩亚洲欧美中文高清在线 | 日日麻批免费40分钟无码 | 日韩精品成人一区二区三区 | 久久天天躁狠狠躁夜夜免费观看 | 欧美大屁股xxxxhd黑色 | 国产人妖乱国产精品人妖 | 无码纯肉视频在线观看 | 国产亚洲人成在线播放 | 一本无码人妻在中文字幕免费 | 亚洲熟妇色xxxxx欧美老妇y | 久久这里只有精品视频9 | 夫妻免费无码v看片 | 国产在线无码精品电影网 | 性色欲网站人妻丰满中文久久不卡 | 日韩精品无码一区二区中文字幕 | 欧美兽交xxxx×视频 | 欧洲极品少妇 | 日韩精品乱码av一区二区 | 亚洲欧洲日本综合aⅴ在线 | 亚洲精品成人av在线 | 成人一在线视频日韩国产 | 日本大乳高潮视频在线观看 | 狠狠色噜噜狠狠狠狠7777米奇 | 欧美35页视频在线观看 | 亚洲国产精品毛片av不卡在线 | 国产特级毛片aaaaaa高潮流水 | 久久久av男人的天堂 | 国产高清不卡无码视频 | 激情内射日本一区二区三区 | 国产精品丝袜黑色高跟鞋 | 在线视频网站www色 | 午夜嘿嘿嘿影院 | 一本久道高清无码视频 | 亚洲乱码中文字幕在线 | 中文字幕无码免费久久99 | 在线成人www免费观看视频 | 少妇人妻大乳在线视频 | 麻豆人妻少妇精品无码专区 | 中文字幕乱码人妻无码久久 | 成人女人看片免费视频放人 | 天下第一社区视频www日本 | 领导边摸边吃奶边做爽在线观看 | 99精品国产综合久久久久五月天 | 无套内谢的新婚少妇国语播放 | 国产两女互慰高潮视频在线观看 | 爱做久久久久久 | 欧美人与禽zoz0性伦交 | 国产乱码精品一品二品 | 久久精品一区二区三区四区 | 国精品人妻无码一区二区三区蜜柚 | 亚洲精品久久久久久一区二区 | 久久精品一区二区三区四区 | 中文字幕日韩精品一区二区三区 | 波多野结衣乳巨码无在线观看 | 无码av中文字幕免费放 | 鲁鲁鲁爽爽爽在线视频观看 | 成人无码视频免费播放 | 国产人妻精品午夜福利免费 | 老头边吃奶边弄进去呻吟 | 国产综合在线观看 | 老子影院午夜伦不卡 | 内射老妇bbwx0c0ck | 天天躁日日躁狠狠躁免费麻豆 | 福利一区二区三区视频在线观看 | 久久熟妇人妻午夜寂寞影院 | 欧美黑人巨大xxxxx | 丝袜足控一区二区三区 | 国产美女精品一区二区三区 | 荫蒂添的好舒服视频囗交 | 嫩b人妻精品一区二区三区 | 人妻少妇精品无码专区二区 | 亚洲成a人片在线观看无码 | 免费无码肉片在线观看 | 色婷婷欧美在线播放内射 | 亚洲第一网站男人都懂 | 国产亚洲精品久久久久久久久动漫 | 大屁股大乳丰满人妻 | 大屁股大乳丰满人妻 | 久久人人97超碰a片精品 | 欧美亚洲日韩国产人成在线播放 | 网友自拍区视频精品 | 色偷偷人人澡人人爽人人模 | 国产成人一区二区三区别 | 亚洲一区二区三区香蕉 | 久久久久久国产精品无码下载 | 久热国产vs视频在线观看 | 丰满人妻精品国产99aⅴ | 久久国产精品_国产精品 | 无码人妻少妇伦在线电影 | 狂野欧美激情性xxxx | 国产精品毛片一区二区 | 日日躁夜夜躁狠狠躁 | 日韩人妻少妇一区二区三区 | 久久午夜无码鲁丝片午夜精品 | 日本护士xxxxhd少妇 | 55夜色66夜色国产精品视频 | 久久人人97超碰a片精品 | 九九久久精品国产免费看小说 | 亚洲欧洲中文日韩av乱码 | 亚洲人成影院在线无码按摩店 | 亚洲欧美色中文字幕在线 | 婷婷综合久久中文字幕蜜桃三电影 | aa片在线观看视频在线播放 | 亚洲一区二区三区含羞草 | 一本精品99久久精品77 | 一本精品99久久精品77 | 国产美女精品一区二区三区 | 日日麻批免费40分钟无码 | 无码乱肉视频免费大全合集 | 性色av无码免费一区二区三区 | 久久综合狠狠综合久久综合88 | 性欧美大战久久久久久久 | 天堂无码人妻精品一区二区三区 | 国产乡下妇女做爰 | 久久久久久久久蜜桃 | 天堂一区人妻无码 | 久久久久久a亚洲欧洲av冫 | 激情国产av做激情国产爱 | 精品久久久久久人妻无码中文字幕 | 精品国产国产综合精品 | 曰韩无码二三区中文字幕 | 午夜福利电影 | 人妻少妇精品无码专区动漫 | 天天拍夜夜添久久精品大 | 最新国产麻豆aⅴ精品无码 | 国产午夜福利100集发布 | 欧美人妻一区二区三区 | 久久国产劲爆∧v内射 | 人人澡人人透人人爽 | 中文无码成人免费视频在线观看 | 荫蒂添的好舒服视频囗交 | 久久综合给久久狠狠97色 | 免费男性肉肉影院 | 国产人妻精品午夜福利免费 | 国产免费久久精品国产传媒 | 国产熟妇另类久久久久 | 亚洲天堂2017无码中文 | 日日摸天天摸爽爽狠狠97 | 色综合久久久无码网中文 | 国产成人无码av在线影院 | 亚洲欧美日韩综合久久久 | 97久久精品无码一区二区 | 国产乱人偷精品人妻a片 | 一个人看的视频www在线 | 亚洲成a人片在线观看无码3d | 一个人看的视频www在线 | 国产无遮挡又黄又爽免费视频 | 欧美zoozzooz性欧美 | 国产性生大片免费观看性 | 精品少妇爆乳无码av无码专区 | 日韩av无码一区二区三区 | 性欧美videos高清精品 | 国产乱人无码伦av在线a | 亚洲日本一区二区三区在线 | 美女张开腿让人桶 | 2019午夜福利不卡片在线 | 欧美35页视频在线观看 | 国产超级va在线观看视频 | 亚洲日韩av一区二区三区四区 | 97久久超碰中文字幕 | 亚洲理论电影在线观看 | 亚洲中文字幕va福利 | 亚无码乱人伦一区二区 | 国内精品人妻无码久久久影院蜜桃 | 秋霞特色aa大片 | 久久久久久久久888 | 久久99久久99精品中文字幕 | 午夜福利一区二区三区在线观看 | 扒开双腿疯狂进出爽爽爽视频 | 久久国产36精品色熟妇 | 波多野结衣av一区二区全免费观看 | 亚洲 a v无 码免 费 成 人 a v | 成人一区二区免费视频 | 麻豆精品国产精华精华液好用吗 | 鲁一鲁av2019在线 | 18精品久久久无码午夜福利 | 久久精品国产大片免费观看 | 蜜臀av在线播放 久久综合激激的五月天 | 成熟妇人a片免费看网站 | 亚洲午夜无码久久 | 国产精品成人av在线观看 | 成人亚洲精品久久久久 | 丰满妇女强制高潮18xxxx | 俺去俺来也在线www色官网 | 美女黄网站人色视频免费国产 | 日本精品少妇一区二区三区 | 成人一在线视频日韩国产 | 亚洲乱亚洲乱妇50p | 婷婷丁香五月天综合东京热 | 奇米影视7777久久精品人人爽 | av小次郎收藏 | 国产香蕉尹人综合在线观看 | 国精产品一品二品国精品69xx | 综合网日日天干夜夜久久 | 成人亚洲精品久久久久软件 | 波多野结衣av一区二区全免费观看 | 中文字幕无码乱人伦 | 国产两女互慰高潮视频在线观看 | 亚洲午夜久久久影院 | 亚洲一区二区三区四区 | 国产婷婷色一区二区三区在线 | 中文字幕乱码中文乱码51精品 | 国产 浪潮av性色四虎 | 久久久婷婷五月亚洲97号色 | 噜噜噜亚洲色成人网站 | 麻豆人妻少妇精品无码专区 | 欧美黑人性暴力猛交喷水 | 久久精品人人做人人综合 | 国产亚洲精品久久久久久大师 | 人人妻人人澡人人爽欧美一区九九 | 成年美女黄网站色大免费视频 | 美女黄网站人色视频免费国产 | 强伦人妻一区二区三区视频18 | 国产内射老熟女aaaa | 亚洲色无码一区二区三区 | 乱人伦人妻中文字幕无码久久网 | 国产猛烈高潮尖叫视频免费 | 在线看片无码永久免费视频 | 内射老妇bbwx0c0ck | 欧美喷潮久久久xxxxx | 曰韩少妇内射免费播放 | 在线成人www免费观看视频 | 97久久国产亚洲精品超碰热 | 正在播放老肥熟妇露脸 | 久久人人爽人人爽人人片ⅴ | 日韩欧美中文字幕公布 | 小sao货水好多真紧h无码视频 | 最近的中文字幕在线看视频 | 牲欲强的熟妇农村老妇女 | 亚洲日韩一区二区三区 | 国产极品美女高潮无套在线观看 | 免费人成在线观看网站 | 撕开奶罩揉吮奶头视频 | 国产成人无码午夜视频在线观看 | 一个人看的www免费视频在线观看 | 成人精品一区二区三区中文字幕 | 国内丰满熟女出轨videos | 欧美精品国产综合久久 | 自拍偷自拍亚洲精品被多人伦好爽 | 少妇被粗大的猛进出69影院 | 国产精品a成v人在线播放 | 国产69精品久久久久app下载 | 久久精品视频在线看15 | 国产精品久久国产三级国 | 中文久久乱码一区二区 | 国产精品高潮呻吟av久久 | 欧美丰满熟妇xxxx性ppx人交 | 玩弄少妇高潮ⅹxxxyw | 久久久久久国产精品无码下载 | 免费无码av一区二区 | 国产精品欧美成人 | 久久精品人人做人人综合 | 激情五月综合色婷婷一区二区 | yw尤物av无码国产在线观看 | 国产亚洲人成a在线v网站 | 中文字幕乱码人妻二区三区 | 性啪啪chinese东北女人 | 特级做a爰片毛片免费69 | 日日摸天天摸爽爽狠狠97 | 网友自拍区视频精品 | 国产精品办公室沙发 | 乌克兰少妇性做爰 | 欧洲欧美人成视频在线 | 九九综合va免费看 | 亚洲人亚洲人成电影网站色 | 无码毛片视频一区二区本码 | 欧美日韩综合一区二区三区 | 任你躁国产自任一区二区三区 | 精品偷拍一区二区三区在线看 | 窝窝午夜理论片影院 | 久久天天躁狠狠躁夜夜免费观看 | 中文字幕+乱码+中文字幕一区 | 国产9 9在线 | 中文 | 亚洲色偷偷男人的天堂 | 日韩精品乱码av一区二区 | 狂野欧美性猛xxxx乱大交 | 粗大的内捧猛烈进出视频 | 久久久www成人免费毛片 | 成年美女黄网站色大免费视频 | 国产精品亚洲lv粉色 | 日本又色又爽又黄的a片18禁 | 少妇性俱乐部纵欲狂欢电影 | 人人妻人人澡人人爽人人精品浪潮 | 少妇久久久久久人妻无码 | 人人妻在人人 | 亚洲熟妇色xxxxx欧美老妇 | 日韩无码专区 | 久久国产精品精品国产色婷婷 | 亚洲精品中文字幕乱码 | 亚洲国产成人a精品不卡在线 | 在线播放无码字幕亚洲 | 熟女少妇在线视频播放 | 久久精品人人做人人综合 | 18禁黄网站男男禁片免费观看 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲综合伊人久久大杳蕉 | 亚洲 激情 小说 另类 欧美 | 国产无套内射久久久国产 | 国产精品免费大片 | 欧美真人作爱免费视频 | 狠狠噜狠狠狠狠丁香五月 | 免费人成在线视频无码 | 1000部夫妻午夜免费 | 97se亚洲精品一区 | 人人爽人人澡人人高潮 | 又紧又大又爽精品一区二区 | 久久www免费人成人片 | 波多野结衣aⅴ在线 | 久久精品中文字幕大胸 | 欧美黑人乱大交 | 亚洲中文字幕无码中文字在线 | 成人一在线视频日韩国产 | 亚洲成a人片在线观看日本 | 国产精品久久久久久久9999 | 国产日产欧产精品精品app | 爆乳一区二区三区无码 | 一个人看的www免费视频在线观看 | 国产精品人人爽人人做我的可爱 | 国精品人妻无码一区二区三区蜜柚 | aⅴ在线视频男人的天堂 | 99er热精品视频 | 97精品国产97久久久久久免费 | 欧美性猛交xxxx富婆 | 伊人久久大香线焦av综合影院 | 国产无遮挡吃胸膜奶免费看 | 97se亚洲精品一区 | 无码国产乱人伦偷精品视频 | 成人片黄网站色大片免费观看 | 国产亚洲人成a在线v网站 | 激情亚洲一区国产精品 | 国产另类ts人妖一区二区 | 少妇一晚三次一区二区三区 | 久久午夜无码鲁丝片午夜精品 | 无码精品国产va在线观看dvd | 偷窥村妇洗澡毛毛多 | 色 综合 欧美 亚洲 国产 | 欧美激情内射喷水高潮 | 秋霞特色aa大片 | 亚洲成在人网站无码天堂 | 亚洲精品久久久久中文第一幕 | 国产色精品久久人妻 | 久久人人爽人人爽人人片ⅴ | 日韩精品乱码av一区二区 | 国产亚洲精品久久久闺蜜 | 亚洲成色www久久网站 | 亚洲精品一区二区三区在线观看 | 日韩亚洲欧美精品综合 | 亚洲 欧美 激情 小说 另类 | 一本久久a久久精品vr综合 | 无遮挡国产高潮视频免费观看 | 日日麻批免费40分钟无码 |