讀書筆記 C 學習筆記七 C 4 0中微小改動

2021-08-01 06:02:17 字數 3981 閱讀 4995

前言

下面就開始總結c#4.0的一些變化了, 也是這本書中最後的一點內容了, 這一部分終於要更新完了. 同時感覺再來讀第二遍也有不一樣的收穫. 今天很嗨的是武漢下雪了,明天週六,一切都是這麼美好.哈哈哈.

主要內容有: 可選引數和命名實參, 泛型的可變性, 動態型別

1,可選引數和命名實參

1.1可選引數

可選引數和命名實參就如同一對好**, 因為它們經常一起使用. 

可選引數重在"可選", 即在呼叫方法時, 該引數可以明確指定實參, 也可以不指定實參.如下**:

1

class program2 9

10//

帶有可選引數的方法

11static

void testmethod(int x, int y = 10, string name = "

barrywang

")12 y = (1) name = ;

", x, y, name);

14 }

15 }

列印結果如下圖:

是不是有一種很神奇的感覺? 這就是可選引數的好用之處, 特別是對於乙個系統的後期維護很好使用, 在真實的專案中我也使用過這樣的用法, 如下例:

在我們做的系統中切換user有switchuser(不lougout當前user,然後新增新的user登陸)和transferuser(logout當前user,然後登陸新的user)兩種方式

但是系統又會進行對登陸的user數量進行限制, 而switchuser和transferuser使用的都是同乙個限定check方法,而兩種對user的操作方式不同,所以導致transferuser會出現問題.

這裡的解決方案就是仍然使用同乙個check方法,但是給這個check方法新新增乙個可選引數來判斷到底是執行的哪個操作, 然後根據不同的操作去做相應的修改.

在使用可選引數時, 需要注意一下幾個約束條件:

(1)所有可選引數必須位於必選引數之後.

(2)可選引數的預設值必須為常亮.

(3)引數陣列(有params修飾符宣告)不能做為可選引數

(4)用ref或out關鍵字標識的引數不能被設定為可選引數

看到這裡我們就可以發現可選引數的最大的優點就是便於系統後期的維護. 其他的優點還有待發現.

1.2命名實參

如果乙個系統中有兩個可選引數, 而我們想省略掉第乙個可選引數怎麼辦呢? 命名實參這個時候就可以幫助我們了.

1

class program

2 15

16//

帶有兩個可選引數的方法

17static

void testmethod(int x, int y = 10, string name = "

barrywang

")18 , y = , name =

", x, y, name);

20 }

21 }

列印結果如下圖:

有了命名實參, 可選引數的變得更加強大了是不是? 哈哈, 確實是這樣.

2,泛型的可變性

在c#2.0 中, 泛型並不具備可變性, 這種是指斜變性和逆變性. 而在c#4.0中引入了泛型的協變性和逆變性.

2.1協變性

協變性指的是泛型型別引數可以從乙個派生類隱式轉化為基類. 大家可以這樣記憶: 協變性即和諧(與"協"同音)的變化,

從派生類轉換為基類, 就如同所子女長的像父母一樣, 聽起來非常和諧. 這樣就很容易記住協變了.

c#4.0引入out關鍵字來標記泛型引數, 以示其支援協變性. 為了更好的進行說明, 下面用.net類苦中的ienumerable介面為例做演示:

1

class program

2 12 }

在以上**中, addrange方法接收的引數型別為ienumerable, 該介面的定義為ienumerable, 因為其泛型引數有out關鍵字標識, 

所以ienumerable泛型的型別引數t支援協變性, 則可將list轉化為ienumerable(這是被繼承的協變性支援的. 因為list實現了ienumerable介面). 

又因為型別引數支援協變性, 所以可以進一步把ienumerable轉化為ienumerable

2.2逆變性

逆變性指的是泛型型別引數可以從乙個基類隱式地轉化為派生類,c#4.0引入in關鍵字來標記泛型引數, 以示其支援逆變性.

下面使用.net類庫中的介面public inte***ce icomparer為例進行演示:

1

class program

2

32 }

3334

public

class testcomparer : icomparer

35 40 }

在以上**中, liststrs變數的sort應接收icomparer型別的引數, 雖然傳入的實參是icomparer型別, 

但因為icomparer泛型介面支援逆變, 所以可將object轉化為string型別.

2.3協變和逆變的注意事項

(1)只有介面和委託才支援協變和逆變, 類或泛型方法的型別引數都不支援協變和逆變

(2)協變和逆變只適用於引用型別, 值型別不支援協變和逆變(例如list無法轉化為ienumerable)

(3)必須顯式地用in或out來標記型別引數

(4)委託的可變性不要再多播委託中使用

3,動態型別

在c#4.0中, 微軟引入了dynamic管家你來定義動態型別. 當我們使用由dynamic關鍵字限制的變數時, 編譯器並不知道它的型別, 該型別智慧型在程式執行時才能被確定.

動態型別的定義為: dynamic i = 5;

動態型別和靜態型別到底有什麼不同呢?

1

object obj = 10;

2 obj = obj + 10;//

出現變異錯誤

3dynamic i = 10;

4 i = i + 10;

解析:

在以上**中, 第一行的obj為objec他型別, 而編譯器卻檢測出"+"運算子無法應用於object和int型別. 

要讓編譯器通過, 我們必須使用強制型別轉換, 把object轉換為int. 即obj = (int)obj + 10;

但是動態型別的引入到底有什麼好處呢?

1,可以減少強制型別轉換的使用. 因為動態型別是在程式執行時才被確定, 使用它可以避免**進行強制型別轉換,從而使**看起來更加簡潔.

2,呼叫python等動態語言. 動態型別除了可以減少強制型別轉換外, 還可以讓我們在c#語言中呼叫python這樣的動態語言.

ps: 想為自己的文字多增加一點內容, 以後每個帖子後面都會加一些口語小貼士, 這些都是自己平時看過的. 英語真的很重要, 這裡不用我多說大家應該都知道的.

口語小貼士:

a fool never learns.

傻瓜永遠學不會

a little bird told me.

我聽說的

are you out of your mind?

你瘋了嗎?

are you pulling my leg?

你在開我玩笑嗎?

as far as i'm concerned.

就我而言

C 讀書筆記

1.內建函式 inline必須在呼叫前進行完整定義,語 define相同,但是消除了不安全性 例 inline float circle float r 2,函式原型 語法形式 返回型別 函式名 參數列 1 函式原型的參數列中不包含引數的名字,而只包含型別 2 函式定義由函式說明部分和函式體構成 3...

C 讀書筆記

c陷阱和缺陷 1.賦值符優先順序比邏輯比較低,賦值表示式的結果為賦值後的結果 2.編譯器掃瞄符號使用貪心法,盡量選擇最長字元的符號串,如a 理解為a 而不是a 3.為相容老版本編譯器,不同符號之間最好加空格,如a 1可能理解為a 1,應該改為a 1 4.老版本編譯器,8進製數以0開始,後面可以加超過...

c 讀書筆記

再看一本叫做 stl lectures 的書,裡面有一段 讓我學習了 include includeusing namespace std template const t max const t x,const t y int main 我說這段 讓我學習,不是說它寫的多好 因為這段 在g 4.8...