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 實現二 上...