C#--學習筆記

一、《C#學習筆記》

目錄:C06 接口(interface)
 C08 委託(delegate)
 C09 事件(Event)
 C10 類型
 C11 泛型(Generic)--使類型參數化
 C12 可空類型、匿名方法和迭代器
 C14 Lambda表達式
 C15 擴展方法--使類的擴展更簡單:(Extension Method)
 C16 LINQ--數據操作So easy
 C17 C#4.0中的微小改動
 C18 動態類型(dynamic)
 C19 多線程編程
 C21 出師前闖關訓練第一關--文件操作
 C22 出師前闖關訓練第二關--網絡編程

 C23 出師前闖關訓練最後一關--使用GDI+實現屬於你的截圖工具

C06 接口(interface):
    接口可以理解爲對一組方法聲明進行的統一命名,但這些方法沒有提供任何實現。
通過接口,可以對方法進行統一管理,避免了在每種類型中重複定義這些方法。
     
C08 委託(delegate):
1.委託(delegate)
委託定義:"委託是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,
         可以避免在程序中大量使用If-Else(Switch)語句,同時使得程序具有更好的可擴展性。"
使用委託的步驟爲:1.定義委託類型->2.聲明委託變量->3.實例化委託->4.作爲參數傳遞給方法->5.調用委託。
委託的最大作用:委託使得一個方法可以作爲另一個方法的參數進行傳遞。
引入委託之後,可以把函數作爲參數傳遞給另一個方法,委託可以提高方法擴展性。
2.委託鏈

C#中把封裝多個方法的委託稱爲委託鏈或多路廣播委託。

C09 事件(Event):
定義:事件基本上說是一個用戶操作,如按鍵、點擊、鼠標移動等等,或者是一些出現,如系統生成的通知。
            應用程序需要在事件發生時響應事件。例如,中斷。事件是用於進程間通信。
事件定義的結構:訪問修飾符 event 委託類型 事件名;例如:public event EventHandler birthday

訂閱和取消事件。

C10 類型:
    值類型和引用類型:
值類型:主要包括簡單類型、枚舉類型、結構體類型等。值類型的實例通常被分配在線程的堆棧上,變量保存的內容就是實例數據本身。

引用類型:主要包括類類型、接口類型、委託類型和字符串類型等。引用類型的實例則被分配再託管堆上,變量保存的是實例數據的內存地址。

C11 泛型(Generic)--使類型參數化:
    泛型代表的就是"通用類型",它可以代替任意的數據類型,使類型參數化,從而達到只實現一個方法就可以操作多種數據類型的目的。
泛型將方法實現行爲與方法操作的數據類型分離,實現了代碼重用。
(1) 類型參數:例如:在 List<T> 中,T就是類型參數。
根據泛型類型參數是否提供實際類型,泛型分爲兩類:未綁定的泛型和已構造的泛型。
開放類型和密封類型。
開放類型是指包含類型參數的泛型,所有未綁定的泛型都屬於開放類型;而封閉類型則是指那些已經爲每一個類型參數都傳遞了實際數據類型的泛型。
實現泛型類的時候,我們使用了where T:IComparable的代碼,其中where語句用來使類型參數繼承於IComparable接口,從而對類型參數進行約束。
(2) 泛型中的靜態字段和靜態函數問題:
每個封閉的泛型類型中都有屬於它自己的靜態字段。
(3) 類型參數的推斷:增強代碼的可讀性。
   // 泛型方法
        private static void genericMethod<T>(ref T t1, ref T t2)
        {
            T temp = t1;
            t1 = t2;
            t2 = temp;
        }
 
 C12 可空類型、匿名方法和迭代器:
(1)Nullable<T>和Nullable :
空合併操作符,即??操作符,它會對左右兩個操作數進行判斷:如果左邊的數不爲null,就返回左邊的數;如果左邊的數爲null,就返回右邊的數。
注:??運算符不能應用於值類型。(除了可空類型外,其他的值類型都是不能與null類型進行比較的。)
可空類型的裝箱和拆箱:當把一個可空類型付給引用類型變量是,CLR會對可空類型(Nullable<T>)對象進行裝箱處理;當把一個已裝箱的值類型付給可空類型變量時,CLR會對已裝箱的值類型進行拆箱處理。
(2)匿名方法:沒有名字的方法。
回顧委託的使用方法:
代碼:12.2.1_1
class Program
{
// 定義投票委託
delegate void VoteDelegate(string name);
static void Main(string[] args)
{
// 使用Vote方法來實例化委託對象
//VoteDelegate votedelegate = new VoteDelegate(new Friend().Vote);
// 下面方式爲隱式實例化委託對象方式,把方法直接賦給委託對象
VoteDelegate votedelegate = new Friend().Vote;
// 通過調用託來回調Vote()方法,此爲隱式調用方式
votedelegate("SomeBody");
Console.Read();
}
public class Friend
{
// 朋友的投票方法
public void Vote(string nickname)
{
Console.WriteLine("暱稱爲:{0} 來幫Learning Hard投票了", nickname);
}
}
}
委託是用來包裝方法的類類型,既然匿名方法也是方法,當然可以被委託類型包裝了,所以我們還可以用匿名方法的方式去實現上面的代碼:
代碼:12.2.1_2
// 匿名方法的使用演示
class Program
{   
// 定義投票委託
delegate void VoteDelegate(string name);
static void Main(string[] args)
{
// 使用匿名方法來實例化委託對象
VoteDelegate votedelegate = delegate(string nickname)
{
Console.WriteLine("暱稱爲:{0} 來幫Learning Hard投票了", nickname);
};
// 通過調用託來回調Vote()方法,此爲隱式調用方式
votedelegate("SomeBody");
Console.Read();
}
}
匿名方法的缺點:不能再其他地方被調用,即不具有複用性。
閉包:指的是在匿名方法中捕捉(即引用)了外部變量。兩個概念:外部變量和被捕捉的外部變量。
代碼:12.2.2
class Program
{
// 定義閉包委託
delegate void ClosureDelegate();
static void Main(string[] args)
{
// 調用方法
closureMethod();
Console.Read();
}
// 閉包方法
private static void closureMethod()
{
// outVariable和capturedVariable對於匿名方法而言都是外部變量
string outVariable = "外部變量";
//  而capturedVariable是被匿名方法捕獲的外部變量
string capturedVariable = "被捕獲的外部變量";
ClosureDelegate closuredelegate = delegate
{
// localvariable是匿名方法中局部變量
string localvariable = "匿名方法局部變量";
// 引用capturedVariable變量
Console.WriteLine(capturedVariable + " " + localvariable);
};
// 調用委託
closuredelegate();
}
}
被匿名方法捕獲的變量是真的變量,而非創建委託實例時該變量的值。被匿名方法捕獲後,變量的生命週期會被延長。
匿名方法是如何延長變量的生命週期的:(對於匿名方法捕捉到的變量,編譯器會額外創建一個類來容納它們)
代碼:代碼12.2.2.2_2
// 閉包演示
class Program
{
// 定義閉包委託
delegate void ClosureDelegate();
static void Main(string[] args)
{
ClosureDelegate test = CreateDelegateInstance();
// 此時會回調匿名方法輸出count的值
test();
Console.Read();
}
// 閉包延長變量的生命週期
private static ClosureDelegate CreateDelegateInstance()
{
// 外部變量
int count = 1;
ClosureDelegate closuredelegate = delegate
{           
Console.WriteLine(count);
// 捕捉了外部變量
count++;
};
// 調用委託
closuredelegate();
return closuredelegate;
}
}
運行結果:1
2
(3)迭代器:

  迭代器記錄了集合中的某個位置,它使程序只能向前移動。

C14 Lambda表達式:
Lambda表達式可以理解爲一個匿名方法,它可以包含表達式和語句,並且用於創建委託或轉換爲表達式樹。
在使用Lambda表達式時,都會使用"=>"運算符(讀作"goes to"),該運算符的左邊是匿名方法的輸入參數,右邊則是表達式或語句塊。
(1)Lambda表達式的演變過程:
代碼:14.1.1
class Program
{
static void Main(string[] args)
{
// Lambda表達式的演變過程
// 下面是C# 1中創建委託實例的代碼
Func<string, int> delegatetest1 = new Func<string, int>(Callbackmethod);
//                                  ↓
// C# 2中用匿名方法來創建委託實例,此時就不需要額外定義回調方法Callbackmethod
Func<string, int> delegatetest2 = delegate(string text)
{
return text.Length;
};
//                      ↓
// C# 3中使用Lambda表達式來創建委託實例
Func<string, int> delegatetest3 = (string text) => text.Length;
//                                  ↓
// 可以省略參數類型string,把上面代碼再簡化爲:
Func<string, int> delegatetest4 = (text) => text.Length;
//                                  ↓
// 此時可以把圓括號也省略,簡化爲:
Func<string, int> delegatetest = text => text.Length;
// 調用委託
Console.WriteLine("使用Lambda表達式返回字符串的長度爲: " + delegatetest("learning hard"));
Console.Read();
}
// 回調方法
private static int Callbackmethod(string text)
{
return text.Length;
}
}
(2)Lambda表達式的使用:
(3)表達式也有樹結構--表達式樹
Lambda表達式除了可以用來創建委託外,還可以轉換成表達式樹。
代碼:14.2.2
using System;
// 引入Expression<TDelegate>類的命名空間
using System.Linq.Expressions;
namespace _14._4
{
class Program
{
static void Main(string[] args)
{
// 將lambda表達式構造成表達式樹
Expression<Func<int, int, int>> expressionTree = (a, b) => a + b;
// 獲得表達式樹參數
Console.WriteLine("參數1:{0},參數2: {1}", expressionTree.Parameters[0], expressionTree.Parameters[1]);
// 獲取表達式樹的主體部分
BinaryExpression body = (BinaryExpression)expressionTree.Body;
// 左節點,每個節點本身就是一個表達式對象
ParameterExpression left = (ParameterExpression)body.Left;
// 右節點
ParameterExpression right = (ParameterExpression)body.Right;
Console.WriteLine("表達式樹主體爲:");
Console.WriteLine(expressionTree.Body);
Console.WriteLine("表達式樹左節點爲:{0}{4} 節點類型爲:{1}{4}{4} 表達式樹右節點爲:{2}{4} 節點類型爲:{3}{4}", left.Name, left.Type, right.Name, right.Type, Environment.NewLine);
Console.Read();
}
}
}
(3)如何把表達式樹轉換成可執行代碼:
  通過Expression<TDelegate>類的Compile()方法將表達式樹編譯成委託實例,然後通過委託調用的方法得到兩個數的和:
  using System;
// 引入Expression<TDelegate>類的命名空間 //表達式樹類
using System.Linq.Expressions;
namespace _14._5
{
class Program
{
static void Main(string[] args)
{
// 將lambda表達式構造成表達式樹
Expression<Func<int, int, int>> expressionTree = (a, b) => a + b;
// 通過調用Compile方法來生成Lambda表達式的委託
Func<int,int,int> delinstance =expressionTree.Compile();
// 調用委託實例獲得結果
int result = delinstance(2, 3);
Console.WriteLine("2和3的和爲:" + result);
Console.Read();
}
}

}

C15 擴展方法--使類的擴展更簡單:(Extension Method)
定義:擴展方法,首先是一種方法,它可以用來擴展已定義類型中的方法成員。用擴展方法來爲現有的類型添加方法,從而解決了使用繼承進行擴展所帶來的所有弊端。

C16 LINQ--數據操作So easy:
    LINQ(Language Intergrated Query),即語言集成查詢。LINQ的提出就是爲了提供一種跨各種數據源的統一的查詢方式。它主要包含4個組件--Linq to Objects、Linq to XML、Linq to DataSet和Linq to SQL。
查詢表達式:
//查詢表達式
var queryExp=from s in collection
   select s;
//點標記法  (另一種表達方式--點標記方式)
var queryExp=collection.Select(s=>s);

點標記法適合查詢條件較少的情況,而查詢表達式則更加註重結構化思維方式,類似於SQL語法。

C17 C#4.0中的微小改動:
    (1)可選參數和命名參數:最大的好處是簡化了C#與COM(Component Object Model,即組件對象模型)組件的互操作。
代碼:17.1.2
class Program
{
static void Main(string[] args)
{
// 省略name參數
TestMethod(2, 14);
// 省略了y和name參數
TestMethod(2);
// 爲部分實參指定名稱,使用命名實參只省略第二個參數
TestMethod(2, name : "Hello");
// 爲所有實參指定名稱
TestMethod(x: 2, y: 20, name: "Hello");
Console.Read();
}
// 帶有可選參數的方法 //x爲必備參數,y、name爲可選參數
static void TestMethod(int x, int y = 10, string name = "LearningHard")
{
Console.WriteLine("x={0} y={1} name={2}", x, y, name);
}
}
使用C#來調用COM的操作。
(2)泛型的可變性--協變性和逆變性:
  協變性:指的是泛型類型參數可以從一個派生類隱式地轉化爲基類。
  逆變性:指的是泛型類型參數可以從一個基類隱式地轉化爲派生類。
  只有接口和委託才支持協變和逆變(如:Func<out TResult>、Action<in T>),類或泛型方法的類型參數都不支持協變和逆變。

  協變和逆變只適用於引用類型,值類型不支持協變和逆變。(因爲可變性存在引用轉換的過程,而值類型變量存儲的就是對象本身,並不是對象的引用)。

C18 動態類型(dynamic):
動態類型的定義:適用dynamic關鍵字

dynamic i=5; //動態類型定義

C19 多線程編程:
    (1).線程(Thread)是進程中的獨立執行單元,對於操作系統而言,它通過調度線程來使應用程序工作。
 分爲前臺線程和後臺線程。
 爲了避免通過Thread手動創建線程而造成的性能損失(進程的創建和銷燬會耗費大量時間),.NET引入了線程池機制。
   (2).線程池:是指用來存放應用程序中要使用的線程集合。
   (3).線程同步:
線程同步技術是指在多線程程序中,爲了保證後者線程,只有等待前者線程完成之後才能繼續執行。
        使用監視器對象實現線程同步:

監視器對象(Monitor)能夠確保線程擁有對共享資源的互斥訪問權,C#通過lock關鍵字來提供簡化的語法。

C20 異步編程:
    (1).異步編程就是把耗時的操作放進一個單獨的線程中進行處理(該線程需要將執行進度反映到界面上)。
(2).異步編程模型--APM:
APM(Asynchronous Programming Mode),即異步編程模型。
異步編程模型允許程序用更少的線程取執行更多的操作。
某個類是否實現了異步編程模型,主要看該類是否實現了返回類型爲IAsyncResult接口的BeginXXX方法和EndXXX方法。
缺點:不支持對異步操作的取消以及不能提供下載進度報告等。
(3).異步編程模型--EAP:
新的異步編程模型--基於事件的異步模式,即EAP(Event-based Asynchronous Pattern)。
在.NET類庫中,只有部分類實現了EAP,共17個。其中BackgroundWorker類,經常被用於實現網絡文件的下載功能(暫停下載、下載進度報告、斷點續傳功能等)。
(4).異步編程模型--TAP: C# 4.0
更簡單的異步編程實現方式--TAP(Task-based Asynchronous Pattern),即基於任務的異步模式。
TaskAsync 爲後綴的方法,通過向該方法傳入CancellationToken參數(IsCancellationRequested屬性來判斷下載操作是否已被取消),通過IProgress<T>接口來實現進度報告的功能。
(5).讓異步編程So easy--C# 5.0中的async 和await

C21 出師前闖關訓練第一關--文件操作:
(1).文件操作核心類:File和FileInfo類
  .Directory和DirectoryInfo類
(2).流(Stream):可以理解爲內存中的字節序列。
(3).對文件進行異步操作。

C22 出師前闖關訓練第二關--網絡編程:
(1).網絡編程基礎知識:
網絡分層總覽:計算機的網絡通信可歸結爲網絡中層與層之間的通信,OSI(Open System Interconnection)模型把網絡通信分成7層:
物理層(physical layer)、數據鏈路層(data link layer)、網絡層(network layer)、傳輸層(transport layer)、應用層(application layer)(最頂層)。
   網絡程序的工作機制:
1)、IP地址:
  一般爲32位(即4個字節)大小,採用點分十進制的格式來表示。例如:127.0.0.1。每個字節用一個十進制的整數來表示,並用點符號來分割各字節。
2)、套接字(Socket): 
  (Socket--"插座")
網絡程序在進行通信時,主機A的程序將需要傳輸的信息寫入其主機的Socket中,該Socket通過與網卡相連的傳輸介質將信息傳輸到主機B的Socket中。然後,主機B的程序從其Socket中讀取該段信息,再將回覆信息寫入到Socket,並通過網絡相連的傳輸介質將信息返回到主機A的Socket中。主機A中的程序從其Socket中讀取回覆信息,這樣就完成了一次通信。
兩個程序之間的數據傳輸是通過套接字來完成的。我們可以將套接字理解爲網絡進程通信過程中所使用的一段緩衝區。
(2).基於TCP的網絡程序的實現:
TCP協議是傳輸層協議,它提供了可靠的雙向傳輸服務,是大多數網絡應用的實現基礎。
TCP的工作過程:
可劃分爲3個階段:<1>連接的建立:3次握手(“發送一個檢驗包給對方然後互相確認的過程”),只有雙方都接到確認信號後,連接才能建立起來。
               <2>傳輸數據。
<3>斷開連接。
(3).基於UDP的網絡程序的實現:
UDP和TCP都是構建在傳輸層(TP層之上)的協議。
TCP是一種面向連接的、可靠的、面向字節流的傳輸協議;而UDP則是一種簡單的、面向數據包的無連接協議,是一種不可靠的傳輸服務。這裏的"無連接",指的是在正式通信前不必與對方先建立連接,即不管對方狀態如何都直接將信息發送過去。
UDP的工作原理:UDP將網絡數據流量壓縮成數據包的形式,每一個數據包使用8個字節(8*8位=64位)來描述包頭信息,剩餘字節則包含具體的傳輸數據。
             UDP包頭(只有8個字節)相當於TCP的包頭(至少20個字節),它很短,由4個兩字節腸的域組成,分別爲源端口、目的端口、用戶數據包長度和校驗和。
   UDP的優勢:1)UDP速度比TCP快
 2)UDP有消息邊界
 3)UDP可以進行一對多傳輸

C23 出師前闖關訓練最後一關--使用GDI+實現屬於你的截圖工具:
(1).什麼是GDI+:
GDI是Graphics Device Interface Plus的縮寫,即"圖形設備接口",它提供了豐富的圖形圖像處理功能。
在C# .NET中,我們通常使用GDI+來處理二維(2D)圖形和圖像,使用DirectX來處理三維(3D)圖形圖像。
(2).筆、畫筆和顏色:
在GDI+中,可使用筆和畫筆對象繪製圖形和文本。
以Pen類的實例來表示筆,用於繪製線段和空心形狀;以Brush類實例來表示畫筆,用於填充形狀和繪製文本;以Color類的實例來表示顏色,用來爲筆和畫筆畫出來的圖形添加顏色。

完!

圖書pdf及源碼下載: https://download.csdn.net/download/jiemoxiangcha/10490158


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章