NET问答: 对 Linq 中的 Union 和 Concat 的用法困惑
生活随笔
收集整理的這篇文章主要介紹了
NET问答: 对 Linq 中的 Union 和 Concat 的用法困惑
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
咨詢區
Prasad Kanaparthi:
我在使用 Union 和 Concat 上有一個困惑,從字面上理解:一個是并集,一個是連接,下面的例子就是我對這兩個擴展方法的理解。
static?void?Main(string[]?args){var?a1?=?(new[]?{?1,?2?}).Union(new[]?{?1,?2?});var?a2?=?(new[]?{?1,?2?}).Concat(new[]?{?1,?2?});var?a3?=?(new[]?{?"1",?"2"?}).Union(new[]?{?"1",?"2"?});var?a4?=?(new[]?{?"1",?"2"?}).Concat(new[]?{?"1",?"2"?});Console.WriteLine($"a1={string.Join(",",?a1)}");Console.WriteLine($"a2={string.Join(",",?a2)}");Console.WriteLine("---------------------------");Console.WriteLine($"a3={string.Join(",",?a3)}");Console.WriteLine($"a4={string.Join(",",?a4)}");Console.ReadLine();}現在問題來了,為什么我切換到 List<T> 上卻是不同的表現呢?參考下面的代碼。
class?Program{static?void?Main(string[]?args){var?lstX1?=?new?List<X1>?{?new?X1?{?ID?=?10,?ID1?=?10?},?new?X1?{?ID?=?10,?ID1?=?10?}?};var?lstX2?=?new?List<X2>?{?new?X2?{?ID?=?10,?ID2?=?10?},?new?X2?{?ID?=?10,?ID2?=?10?}?};var?a5?=?lstX1.Cast<X>().Union(lstX2.Cast<X>());var?a6?=?lstX1.Cast<X>().Concat(lstX2.Cast<X>());Console.WriteLine($"a5.Count={a5.Count()},?a6.Count={a6.Count()}");Console.ReadLine();}}class?X{public?int?ID?{?get;?set;?}}class?X1?:?X{public?int?ID1?{?get;?set;?}}class?X2?:?X{public?int?ID2?{?get;?set;?}}為什么結果是兩個 4 呢 ?給個建議吧 ????
回答區
Sergey Berezovskiy:
Union 返回的是 Distinct 的值,默認情況下會比較這些 items 的引用,你的 items 其實都是不同的引用值,即使你轉成基類 X,引用值也不會被改變。
如果你重寫了 item 的 Equals 和 GetHashCode 的話,那么 items 之間的比較就不會按照默認的引用比較了,參考如下代碼。
class?X {public?int?ID?{?get;?set;?}public?override?bool?Equals(object?obj){X?x?=?obj?as?X;if?(x?==?null)return?false;return?x.ID?==?ID;}public?override?int?GetHashCode(){return?ID.GetHashCode();} }可以再次運行一下,你將會看到 Union 和 Concat 不同的表現啦。
點評區
這道題感覺可以做面試題,挺有意思的,用了一個障眼法,以為都轉成基類 X 就可以瞞過 CLR 了,有點自作聰明哈????,對象從生下來的那一刻起,他就有專屬的內存地址啦。。。(不討論GC壓縮????)
總結
以上是生活随笔為你收集整理的NET问答: 对 Linq 中的 Union 和 Concat 的用法困惑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF 仿QQ登录框翻转效果
- 下一篇: Azure data studio 跨平