linq
提供了方便的語法和很多操作
物件集合的有用的方法。但是,要讓
linq
比較方法如
distinct
或intersect
能正確處理,型別必須要滿足一些條件。
讓我們看看distinct方法,它從集合中返回所有的不重複物件。
listnumbers = new list;
var distinctnumbers = numbers.distinct();
foreach (var number in distinctnumbers)
console.writeline(number);
輸出:1 2
3但是如果你想在你自定義型別物件的集合使用distinct方法呢?例如,像這樣:
class number
public string textual }
class program
, new number ,
new number ,
new number ,
};var distinctnumbers = numbers.distinct();
foreach (var number in distinctnumbers)
console.writeline(number.digital);
}}
**可以通過編譯,但輸出卻不一樣:11
23為什麼會這樣?答案在linq的實現細節裡。要讓distinct方法正確處理,型別必須實現iequatable介面且提供它自己的equals和gethashcode方法。
(譯註:
根據我的實驗,其實只需正確的重寫object的equals和gethashcode方法便可,並非必須實現iequatable)
那麼,上個例子的number類實際上需要看起來像這樣:
class number: iequatable
public string textual
public bool equals(number other)
// 如果比較兩個物件是相等的,
// 那麼這兩個物件的gethashcode方法必須返回一樣的值。
public override int gethashcode()
}
但假如你無法改變此型別呢?如果它在乙個庫里而你沒有辦法讓此型別實現
iequatable
介面呢?答案是建立乙個你自己的比較器然後將其通過引數傳遞給
distinct
方法。相等比較器必須實現
iequalitycomparer
介面,且同樣提供
gethashcode
和equals
方法。這裡是怎麼為原
number
類實現相等比較器,大概像這樣:
class numbercomparer : iequalitycomparer
public int gethashcode(number number)
}
不要忘記將比較器傳遞給
distinct
方法:var
distinctnumbers = numbers.distinct(
newnumbercomparer
());
當然,這個規則不僅僅適用於
distinct
方法。例如,同樣可以用於
contains
,except
,intersect
,和union
方法。通常,如果你看到此
linq
方法有個接受
iequalitycomparer
引數的過載,這可能表示對你自己的型別使用此方法時,你需要在你的類中實現
iequatable
介面或建立你自己的相等比較器
(譯註:
同上,正確重寫object的equals和gethashcode便可)。
自定義內建方法來定製類的功能
1 str 方法 在物件被列印時,自動觸發,應該在該方法內採集與物件self有關的資訊,然後拼成字串返回 class people def init self,name,age self.name name self.age age def str self print return self.na...
thinkphp使用自定義類方法
1.通過model呼叫 積分模型 api介面 class apimodel elseif firstchar dump json decode res,true 沒有繼承model,否則會因為表不存在而報錯。呼叫,api d api api test 呼叫確實方便,但是總感覺有點不合理。這個d畢竟是...
thinkphp使用自定義類方法
1.通過model呼叫 積分模型 api介面 class apimodel elseif firstchar dump json decode res,true 沒有繼承model,否則會因為表不存在而報錯。呼叫,api d api api test 呼叫確實方便,但是總感覺有點不合理。這個d畢竟是...