擴充套件IList物件,實現深拷貝擴充套件方法

2022-02-04 14:31:03 字數 1602 閱讀 9591

對乙個集合進行深拷貝複製,實現的方法有不少,現舉乙個常規實現方案:例如已有乙個listsomelist

listnewlist = new list();

foreach(var item in somelist)

如果類似的需求不止乙個,那我們就要反覆書寫類似的**,這顯然不符合**重用的原則。

首先想到的應該是擴充套件方法,並且是基於泛型的擴充套件方法,這個簡單,上**:

public

static ilistclone(this ilistsource)

return newlist;

}

這個add方法裡還是要new乙個t物件,並且挨個給屬性賦值,那豈不是也很麻煩,這時候肯定有同學想到了反射,對,使用反射可以解決這個問題,但我認為還不是很理想。

第二次思考。。。對了,微軟不是已經為我們提供了乙個介面叫icloneable的麼?我們應該為t加上約束,修改**如下:

public

static ilistclone(this ilistsource)

where t : icloneable

return newlist;

}

現在看上去還不錯了,基本思路已經成型,在呼叫的時候可以這樣使用: newlist = somelist.clone();

當然,別忘了給你的t加上icloneable介面,並實現clone方法,實現clone的方法有很多,個人建議如下:

public

object clone()

使用序列化的方式進行物件的複製,這樣做的前提是你的class需要被標記為serializable。

例如乙個entity有很多關聯的實體(主子表),現在需要複製原始記錄作為乙份全新的記錄,包括所有的子表,如果採用常規方法,做起來是會很繁瑣的,需要挨個遍歷子表集合,並new乙個全新的實體物件,再挨個執行addobject,如果採用上面的方案,**如下:

//

子表集合

var reslist = this.resourceplanservice.getlist(t => t.quoteid == quoteid).tolist();

foreachcopy(reslist, this.resourceplanservice);

private

void foreachcopy(ilistlist, tservice service)

where tservice : iservice

where tmodel : icloneable

這樣**就精簡了很多,對原來的改動也相對較小,只需要把tmodel的基類entityobjectbase實現icloneable介面,並實現clone方法即可,需要注意的是,如果ef採用db first方式,則需要在clone方法裡面把entitykey設定為null,否則,在呼叫addobject的時候,objectmanagement會丟擲異常。

優點:**簡單、復用度高

缺點:需要修改類物件以繼承icloneable介面,如果沒有基類的話,也是乙個很麻煩的問題,並且類物件需要被標記為serializable

物件深拷貝

最近在專案中用到了物件拷貝這一塊,而且用到的是物件的深拷貝。下面就讓我們來看一下關於物件的拷貝 淺拷貝和深拷貝。先看一下深拷貝和淺拷貝的區別 概念 js 中的淺拷貝與深拷貝,只是針對複雜資料型別 object,array 的複製問題。淺拷貝與深拷貝都可以實現在已有物件上再生出乙份的作用。但是物件的例...

js 物件深拷貝 深拷貝與淺拷貝

前言 最近在複習一些面試的知識點,剛剛好複習到了這一部分,於是就寫下這篇文章記錄一下。一 值型別和引用型別 在學習深拷貝和淺拷貝之前,我們先來了解一下js的變數型別。值型別 vs 引用型別 值型別 值型別主要有 number,string,boolean,symbol,null,undefined ...

物件陣列的深拷貝和物件的深拷貝

1 對於 普通陣列 陣列元素為數字或者字串 深拷貝很簡單,拷貝之後兩個陣列指標指向的儲存位址不同,從而完成深拷貝 var test 1,2,3 原陣列 var testcopy concat test 拷貝陣列 testcopy 0 4 console.log test 1,2,3 console....