1 5 6 泛型方法

2021-09-26 13:08:33 字數 3453 閱讀 2793

除了定義泛型類,泛型結構外,還可以定義泛型放啊發,泛型方法可以在泛型型別定義 ,也可以在非泛型類中定義。

下面是定義的乙個泛型方法,該泛型型別用於兩個引數。(前面有介紹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可以使用任意的字母代替。表示定義了一種不確定的資料型別,這種不確定的資料型別必須在使用這個類 比如建立物件 的時候才能確定下來。如果希望縮小泛型的範圍,延後泛型的確定時間,讓泛型在呼叫方法的時候確定,那麼我們可以使用泛型...