除了定義泛型類,泛型結構外,還可以定義泛型放啊發,泛型方法可以在泛型型別定義 ,也可以在非泛型類中定義。
下面是定義的乙個泛型方法,該泛型型別用於兩個引數。(前面有介紹ref關鍵字)
void swap(ref t x, ref t y)
通過傳入型別來呼叫泛型類:
int i = 4;
int j = 5;
swap(ref i, ref j);
但是泛型方法在編譯的時候會根據傳入引數自動獲取泛型型別,因此沒必要傳入泛型型別,所以在呼叫的時候就會像平常呼叫方法一樣了。
int i = 4;
int j = 5;
swap(ref i, ref j);
首先建立乙個賬戶的類:
public class account
public decimal balance
public account(string name, decimal balance)
}
向類中新增資料:
var accounts = new list()
;
定義乙個泛型方法,用來便利列表,並將用於的金額加起來。
public static class algorithms
return sum;}}
然後去呼叫就可以了
console.writeline(algorithms.accumulate******(accounts));
console.readkey();
我們把上述例子的方法改為含泛型約束的方法:
public static decimal accumulate(listsource) where taccount : iaccount
return sum;
}
當我們再次呼叫的時候,就會出現編譯錯誤。
這時,我們需要建立乙個介面iaccount ,然後讓account去繼承它,即可。
public class account :iaccount
public decimal balance
public account(string name, decimal balance)
}public inte***ce iaccount
decimal balance
}
然後去呼叫,同樣呼叫的時候可以省略引數的型別
console.writeline(algorithms.accumulate(accounts));
console.writeline(algorithms.accumulate>(accounts));//省略引數型別
上述方法存在著乙個缺點,如果我們不知道傳入的型別是什麼,也不知道裡面的變數(balance)是什麼,那麼我們就無法對其做求和運算,那麼接下來我們使用泛型委託來解決這個問題
首先我們來修改該方法,我們不知道返回的型別是什麼,也不知道傳入的型別是什麼,只知道我們要做集合的運算
public static t1 accumulate(listsource,funcaction)
這裡只是簡單的介紹一下泛型委託,在第八章將會更為細節的講解。
定義乙個t1為返回型別,定義乙個t2為list集合的型別,那麼該t1,t2需要在方法邊宣告,接下來就是委託,func要求我們傳入乙個lambda表示式。因為我們不知道要些什麼方法,也不知道怎麼寫,那麼我們需要傳入3個泛型型別,第乙個,給誰賦值t2,第二個,操作誰t2,或許更多給誰賦值,操作誰t3,t4,t5...,這個方法只有兩個,那麼最後乙個引數j就是該方法的返回型別t1。
t1 sum = default(t1);
foreach (t2 item in source)
return sum;
這就是方法體了,因為我們不知道返回型別是什麼,那麼我們就必須定義乙個t1型別的泛型變數,並賦值給預設值default(t1),如果是值型別那麼為0,如果為引用型別,那麼為null。
接下來就是foreach迴圈,因為我們不知道該怎麼寫,所以我們只是使用乙個action方法來替代,傳入需要的引數即可。
接下來就是呼叫了。
algorithms.accumulate(accounts, (a, sum) => sum +=a.balance)
呼叫時,我們不能再省略了,因為有兩個泛型類,所以我們要知道各個泛型類代表著什麼,根據 提示傳入引數。在傳入accouts之後,我們需要傳入lambda表示式,用來當成乙個方法,也可以不傳lambda表示式。
傳入lambda表示式,(a,sum)首先是兩個引數,然後後面是計算。因為我們在定義的時候item為t2型別,sum為t1型別,所有當我們傳入兩個引數(a,sum)分別對應的為t2型別和t1型別,那麼a.就能點出來banlace了。
我們可以對泛型方法進行過載,以達到我們專門化的需求,接下來我們先看四個方法:
public class methodoverloads
第乙個方法,傳入的是泛型型別,第二個方法時int引數的專用方法,第三個方法時傳入兩個泛型引數。
第四個是第三種方法的過載,如果傳入的是int型別的引數,那麼就會選擇帶有int型別的方法,即第四個方法,如果傳入的沒有int型別,那麼就會選擇第三個方法。
如果我們使用以下呼叫方法進行呼叫的話:
var test = new methodoverloads();
test.foo(33);
test.foo("abc");
test.foo("abc", 42);
test.foo(33, "abc");
就會得到以下結果。
我們需要注意的是:泛型方法到底呼叫哪乙個方法在執行時是不確定的,而是在編譯期間進行選擇的。
我們可以做乙個實驗:
採用第五個方法去呼叫第乙個方法,輸出的結果為:
var test = new methodoverloads();
test.bar(44);
console.readkey();
可以看出如果在執行時指定函式,那麼就一定會呼叫那個函式,而不是在編譯的時候自己去選擇。 15 6 利用泛型構建複雜模型
在本例中,構建的是乙個零售店,它包含走廊,貨架,商品 class product override public string tostring public static generatorgenerator new generator class self extends arraylist c...
泛型 泛型類 泛型方法 泛型擦除
1 是什麼?一種允許我們在不確定引數型別時候使用的型別。例如我不知道a方法應該會傳string還是int,我就用個泛型先佔坑。2 為什麼要用泛型?泛型可以在編譯期自動確定具體型別,檢查型別是否匹配,可以提高 的重用率,減少冗餘編碼。3 泛型與object的區別?像上面說的我不知道方法a的引數型別,其...
泛型類,泛型方法,泛型介面
泛型,就是一種不確定的資料型別。如果在類後面加上 這個類就變成了泛型類。這個 t可以使用任意的字母代替。表示定義了一種不確定的資料型別,這種不確定的資料型別必須在使用這個類 比如建立物件 的時候才能確定下來。如果希望縮小泛型的範圍,延後泛型的確定時間,讓泛型在呼叫方法的時候確定,那麼我們可以使用泛型...