C 函式式程式設計之泛型(下)

2022-09-23 20:54:20 字數 2722 閱讀 3208

c#函式式程式設計之約束型別

每當使用泛型型別時,可以通過where字句對泛型新增約束:  

static void outputvalue(t value) where t : listitem

", value.value);

}這個例子直觀地宣告了乙個約束:型別t必須與listitem相匹配。泛型型別約束t:x表示t可以是x、x的派生物件或x的實現(假如x是乙個介面)。換言之,假如型別t的乙個例項為t,則可以把它賦給乙個變數:x x=t;

約束可以使用具體的型別,但是在這些情形下,型別不可以是密封的。有幾個特殊的關鍵字可以取代或補充型別宣告符。關鍵字class表示此型別必須是乙個引用型別,而struct表示它必須是乙個值型別。當new()與class或者任何具體型別一起使用時,可以給這個型別定義乙個預設的建構函式。

約束的最後乙個應用是定義兩個型別引數的關係。例如,對於型別引數的t和u,約束t:u表示t必須與u相容。

使用約束時,有一點必須記住:泛型的基本作用是提供乙個型別安全的方法,使**可以處理不同型別的資料。約束用得越多,則離這個思想越遠,因為約束降低了靈活性。

c#函式式程式設計之其他泛型型別

除了方法與類外,結構體、委託和介面也可以使用型別引數。結構體和介面使用型別引數是顯而易見的,其用法與類相似:

public struct mypoint where t : struct

private readonly t x;

public t x

}private readonly t y;

public t y

}public inte***ce ilistitem

listitem prepend(t value);

}}即使是委託,其用法也絲毫沒有令人吃驚的地方:  

public delegate r createdelegate(t param);

public class paramete***ctory

}使用了泛型後,這些委託幾乎可以代表任何函式。

c#函式式程式設計之協變與逆變

如果乙個操作保留了型別原來的順序,則成為協變,如果顛倒它們的順序,則稱為逆變。所謂的型別順序是指:通用型別的順序值比專用型別的順序值強。

下面這個例子說明c#支援協變,首先定義乙個物件陣列:  

object objects = new object[3];

objects[0] = new object();

objects[1]="just a string";

objects[2]=10;

可以把不同的值插入到這個陣列中,因為所有資料最終都是派生自.net中的object型別。換言之,object是乙個非常通用的型別,即它是乙個強型別。接下來說明.net支援協變,它把乙個弱型別的值賦給強型別的變數:  

string stringstest = new string ;

objects = stringstest;

變數objects屬於object型別,它可以儲存實際型別為string的值。仔細想想,我們希望如此,但是結果不是這樣的,畢竟,雖然string派生自object,但是string並不是派生自object。儘管如此,由於本例中c#支援協變,這個賦值是可行的。

說明逆變思想需要乙個比較複雜的例子:  

public class person:iperson} 

public class woman : person

}woman是從person派生出來的類,現在分析如下兩個函式:  

static void workwithperson(person person)

static void workwithwonman(woman woman)

其中乙個函式作用於woman類,另乙個函式比較通用,作用於person類。從woman類可以定義以下兩個委託和函式:  

delegate void acceptwomandelegate(woman person);

static void dowork(woman woman, acceptwomandelegate acceptwoman)

dowork函式接受乙個woman引數和乙個函式引用,後者也接受乙個woman引數。dowork函式把woman例項傳遞給委託。元素型別大小為:person比woman強,workwithperson比workwithwoman強,為了應用逆變,在此認為workwithperson比acceptwomandelegate強,看以下三行**:  

woman woman = new woman();

dowork(woman, workwithwonman);

dowork(woman, workwithperson);

首先建立乙個woman例項,然後呼叫dowork函式,把woman例項和workwithwoman方法的引用位址傳遞給dowork。後者顯然是與委託型別acceptwomandelegate相容——兩者都只有乙個woman型別引數,沒有返回值。但第三行**有點怪,根據acceptwomandelegate的要求,workwithperson方法接受乙個person引數,而不是乙個woman引數。雖然如此,workwithperson還是與委託型別相容,這是逆變的緣故。

因此,在委託型別下,強型別可以儲存在弱型別的變數中。

變異也能應用在泛型中。如下**:  

list objectlist = new list();

list stringlist = new list();

objectlist = stringlist;

C 泛型程式設計之函式模板

模板是泛型程式設計的基礎,包括函式模板和類模板兩類 其作用是建立乙個通用函式,該函式的返回值和形參型別不具體而用乙個虛擬型別代表,達到簡化的目的 語法templatet 為通用資料型別 如要實現兩數交換的函式 int型別的寫法如 void swapint int a,int b 而如果要交換doub...

C 泛型程式設計之函式模板

泛型程式設計是c 的另一種程式設計思想,主要用到技術是模板。c 提供兩種模板機制 函式模板和類模板 一 函式模板 語法 template函式宣告或定義解釋 template 宣告建立模板 typename 表面其後面的符號是一種資料型別,可以用class代替 t 通用的資料型別,名稱可以替換,通常為...

泛型程式設計之泛型引數

問題 用c 語言實現求乙個數的平方。分析 乙個數,可以是int double complex等,規則求數的平方 x x 偽 sqrt x return x x 實現一 提供一組用於求不同數字型別的平方函式。int sqrtint int x int sqrtdouble double x 實現二 上...