![NET的深復(fù)制方法(以C#語言為例)_第1頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/23/025eb67f-198e-436d-aac6-9f85cabfdf97/025eb67f-198e-436d-aac6-9f85cabfdf971.gif)
![NET的深復(fù)制方法(以C#語言為例)_第2頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/23/025eb67f-198e-436d-aac6-9f85cabfdf97/025eb67f-198e-436d-aac6-9f85cabfdf972.gif)
![NET的深復(fù)制方法(以C#語言為例)_第3頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/23/025eb67f-198e-436d-aac6-9f85cabfdf97/025eb67f-198e-436d-aac6-9f85cabfdf973.gif)
![NET的深復(fù)制方法(以C#語言為例)_第4頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/23/025eb67f-198e-436d-aac6-9f85cabfdf97/025eb67f-198e-436d-aac6-9f85cabfdf974.gif)
![NET的深復(fù)制方法(以C#語言為例)_第5頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/23/025eb67f-198e-436d-aac6-9f85cabfdf97/025eb67f-198e-436d-aac6-9f85cabfdf975.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、NET的深復(fù)制方法(以C#語言為例)深復(fù)制需要將對(duì)象實(shí)例中字段引用的對(duì)象也進(jìn)行復(fù)制,在平時(shí)的編程工作中經(jīng)常要用到這種復(fù)制方式,下面以c#為例來演示一下方法。很多時(shí)候我們復(fù)制一個(gè)對(duì)象實(shí)例A到實(shí)例B,在用實(shí)例B去做其他事情的時(shí)候,會(huì)對(duì)實(shí)例B進(jìn)行修改,為保證對(duì)B的修改不會(huì)影響到A的正常使用,就需要使用到深復(fù)制。 我在網(wǎng)上搜到一些深復(fù)制的方法,同時(shí)寫了幾組例子對(duì)這些方法進(jìn)行測(cè)試。 我的操作系統(tǒng)版本為Win7旗艦版,.NET Framework版本是4.5 測(cè)試程序 我建了一個(gè)C#窗體應(yīng)用程序(Winform),其主窗口FormMain的Load函數(shù)內(nèi)容如下:private void FormMain_
2、Load(object sender, EventArgs e) /測(cè)試1:深度復(fù)制 自定義類 try Console.WriteLine(= 深度復(fù)制 自定義類 =); TestClass test1 = new TestClass(); test1.a = 10; test1.b = hello world!; test1.c = new string x, y, z ; TestClass test2 = new TestClass(); test2.a = 11; test2.b = hello world2!; test2.c = new string i, j, k ; test1
3、.d = test2; Console.WriteLine(-test1_start-); Console.WriteLine(test1); Console.WriteLine(-test1_end-); TestClass test3 = (TestClass)DataManHelper.DeepCopyObject(test1); Console.WriteLine(-test3_start-); Console.WriteLine(test3); Console.WriteLine(-test3_end-); catch (Exception ex) Console.WriteLine
4、(ex.ToString(); /測(cè)試2:深度復(fù)制 可序列化的自定義類try Console.WriteLine(= 深度復(fù)制 可序列化的自定義類 =); TestClassWithS test1 = new TestClassWithS(); test1.a = 10; test1.b = hello world!; test1.c = new string x, y, z ; TestClassWithS test2 = new TestClassWithS(); test2.a = 11; test2.b = hello world2!; test2.c = new string i,
5、j, k ; test1.d = test2; Console.WriteLine(-test1_start-); Console.WriteLine(test1); Console.WriteLine(-test1_end-); TestClassWithS test3 = (TestClassWithS)DataManHelper.DeepCopyObject(test1); Console.WriteLine(-test3_start-); Console.WriteLine(test3); Console.WriteLine(-test3_end-);catch (Exception
6、ex) Console.WriteLine(ex.ToString(); /測(cè)試3:深度復(fù)制 DataTabletry Console.WriteLine(= 深度復(fù)制 DataTable =); DataTable dtKirov = new DataTable(TestTable); dtKirov.Columns.Add(Col1); dtKirov.Columns.Add(Col2); dtKirov.Columns.Add(Col3); dtKirov.Rows.Add(1-1, 1-2, 1-3); dtKirov.Rows.Add(2-1, 2-2, 2-3); dtKirov.
7、Rows.Add(3-1, 3-2, 3-3); Console.WriteLine(= 復(fù)制前 =); for (int i = 0; i dtKirov.Columns.Count; i+) Console.Write(dtKirov.Columnsi.ColumnName + t); Console.WriteLine(n-); for (int i = 0; i dtKirov.Columns.Count; i+) for (int j = 0; j dtKirov.Rows.Count; j+) Console.Write(dtKirov.Rowsij.ToString() + t)
8、; Console.WriteLine(); Console.WriteLine(); DataTable dtDreadNought = (DataTable)DataManHelper.DeepCopyObject(dtKirov); Console.WriteLine(= 復(fù)制后 =); for (int i = 0; i dtDreadNought.Columns.Count; i+) Console.Write(dtDreadNought.Columnsi.ColumnName + t); Console.WriteLine(n-); for (int i = 0; i dtDrea
9、dNought.Columns.Count; i+) for (int j = 0; j System.ArgumentOutOfRangeException: 指定的參數(shù)已超出有效值的范圍。 參數(shù)名: value 在 System.Windows.Forms.DataGridView.set_FirstDisplayedScrollingColumnIndex(Int32 value) - 內(nèi)部異常堆棧跟蹤的結(jié)尾 - 在 System.RuntimeMethodHandle.InvokeMethod(Object target, Object arguments, Signature sig
10、, Boolean constructor) 在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object parameters, Object arguments) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture) 在 System.Reflection.RuntimePrope
11、rtyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object index, CultureInfo culture) 在 System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object index) 在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:MyProgramsDataCopyTestDataCopyTe
12、stDataManHelper.cs:行號(hào) 29 在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:MyProgramsDataCopyTestDataCopyTestFormMain.cs:行號(hào) 141 結(jié)論:使用這種方法進(jìn)行所謂深復(fù)制,完全是自尋死路! 測(cè)試深復(fù)制方法3public static object DeepCopyObject(object obj) if (obj != null) object result = Activator.CreateInstance(obj.GetType
13、(); foreach (FieldInfo field in obj.GetType().GetFields() if (field.FieldType.GetInterface(IList, false) = null) field.SetValue(result, field.GetValue(obj); else IList listObject = (IList)field.GetValue(result); if (listObject != null) foreach (object item in (IList)field.GetValue(obj) listObject.Ad
14、d(DeepCopyObject(item); return result; else return null; 五個(gè)場(chǎng)景的測(cè)試結(jié)果為: I、可正常復(fù)制() II、可正常復(fù)制() III、未觸發(fā)異常, 復(fù)制后DataTable無行列 IV、未觸發(fā)異常,Text字段未賦值 V、未觸發(fā)異常 結(jié)論:這個(gè)方法只適用于深復(fù)制具備簡單結(jié)構(gòu)的類(如類中只有基礎(chǔ)字段、數(shù)組等),對(duì)于不支持序列化的對(duì)象也可以進(jìn)行深復(fù)制。 測(cè)試深復(fù)制方法4 這段代碼來源同方法3public static object DeepCopyObject(object obj) if (obj = null) return null; T
15、ype type = obj.GetType(); if (type.IsValueType | type = typeof(string) return obj; else if (type.IsArray) Type elementType = Type.GetType( type.FullName.Replace(, string.Empty); var array = obj as Array; Array copied = Array.CreateInstance(elementType, array.Length); for (int i = 0; i array.Length;
16、i+) copied.SetValue(DeepCopyObject(array.GetValue(i), i); return Convert.ChangeType(copied, obj.GetType(); else if (type.IsClass) object toret = Activator.CreateInstance(obj.GetType(); FieldInfo fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (F
17、ieldInfo field in fields) object fieldValue = field.GetValue(obj); if (fieldValue = null) continue; field.SetValue(toret, DeepCopyObject(fieldValue); return toret; else throw new ArgumentException(Unknown type); 五個(gè)場(chǎng)景的測(cè)試結(jié)果為: I、可正常復(fù)制() II、可正常復(fù)制() III、觸發(fā)異常MissingMethodException “System.MissingMethodExc
18、eption”類型的第一次機(jī)會(huì)異常在 mscorlib.dll 中發(fā)生 System.MissingMethodException: 沒有為該對(duì)象定義無參數(shù)的構(gòu)造函數(shù)。 在 System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 在 System.RuntimeType.CreateInsta
19、nceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 在 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 在 System.Activator.CreateInstance(Type type, Boolean nonPublic) 在 S
20、ystem.Activator.CreateInstance(Type type) 在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:MyProgramsDataCopyTestDataCopyTestDataManHelper.cs:行號(hào) 45 在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:MyProgramsDataCopyTestDataCopyTestDataManHelper.cs:行號(hào) 53 在 DataCopyTest.FormMai
21、n.FormMain_Load(Object sender, EventArgs e) 位置 d:MyProgramsDataCopyTestDataCopyTestFormMain.cs:行號(hào) 99 IV、未觸發(fā)異常,但Text字段也未賦值成功 V、觸發(fā)異常MissingMethodException “System.MissingMethodException”類型的第一次機(jī)會(huì)異常在 mscorlib.dll 中發(fā)生 System.MissingMethodException: 沒有為該對(duì)象定義無參數(shù)的構(gòu)造函數(shù)。 在 System.RuntimeTypeHandle.CreateInsta
22、nce(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 在 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 在 System.RuntimeType.Creat
23、eInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 在 System.Activator.CreateInstance(Type type, Boolean nonPublic) 在 System.Activator.CreateInstance(Type type) 在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:MyProgramsDataCopyTe
24、stDataCopyTestDataManHelper.cs:行號(hào) 45 在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:MyProgramsDataCopyTestDataCopyTestDataManHelper.cs:行號(hào) 53 在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:MyProgramsDataCopyTestDataCopyTestFormMain.cs:行號(hào) 141 結(jié)論:這個(gè)方法的作用類似方法3,只能深復(fù)制
25、基本數(shù)據(jù)類型組成的類 具體問題具體分析 從上面的例子可以看出,想找一個(gè)放之四海而皆準(zhǔn)的方式去深復(fù)制所有對(duì)象是很困難的。一些使用高級(jí)語言特性(反射)的深復(fù)制方法,即使可以在部分類上試用成功,也無法對(duì)所有的類都具備十足的把握。因此我認(rèn)為應(yīng)該采取下面的方式處理對(duì)象的深復(fù)制問題: 1、對(duì)于由基本數(shù)據(jù)類型組成的類,為之打上Serializable標(biāo)簽,直接使用序列化與反序列化的方法進(jìn)行深復(fù)制 2、其他較為復(fù)雜的類型如DataGridView,可根據(jù)自身情況寫一個(gè)方法進(jìn)行深復(fù)制,之所以在這里說要根據(jù)自身情況寫方法,是因?yàn)樵趯?duì)很多類進(jìn)行復(fù)制時(shí),你只需要復(fù)制對(duì)你有用的屬性就行了。如TextBox控件中,只有T
26、ext一個(gè)屬性對(duì)你是有用的,如果你需要在復(fù)制后的對(duì)象中用到Readonly等屬性的值,那么在你自己實(shí)現(xiàn)的復(fù)制方法中,也加上對(duì)這些屬性的賦值即可。這樣做還有一個(gè)好處,就是方便進(jìn)行一些定制化的開發(fā)。 如下面這段代碼,就是對(duì)DataGridView的一個(gè)近似的深復(fù)制,這段代碼將一個(gè)DataGridView(dgv)的內(nèi)容復(fù)制到另一個(gè)DataGridView(dgvTmp)中,然后將dgvTmp傳遞給相關(guān)函數(shù)用于將DataGridView中的內(nèi)容輸出到Excel文檔:DataGridView dgvTmp = new DataGridView();dgvTmp.AllowUserToAddRows = false; /不允許用戶生成行,否則導(dǎo)出后會(huì)多出最后一行for (int i = 0; i dgv.Columns.Count; i+) dgvTmp.Columns.Add(dgv.Columnsi.Name, dgv.Columnsi.HeaderText); if (dgv.Columnsi.Defa
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2012建筑租賃合同范本
- 人防租賃轉(zhuǎn)讓合同范本
- 分項(xiàng)勞務(wù)合同范本
- 加盟銷售合同范例
- 人情補(bǔ)償寫合同范本
- 出租車司機(jī)加盟合同范本
- 2025年中國恒轉(zhuǎn)矩變頻器行業(yè)市場(chǎng)深度研究及投資戰(zhàn)略規(guī)劃報(bào)告
- 上海建筑施工合同范本
- 2025年中國工業(yè)防水插座行業(yè)市場(chǎng)發(fā)展前景及發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- 公司聯(lián)營股合同范本
- 中國氫內(nèi)燃機(jī)行業(yè)發(fā)展環(huán)境、市場(chǎng)運(yùn)行格局及前景研究報(bào)告-智研咨詢(2024版)
- 開學(xué)季初三沖刺中考開學(xué)第一課為夢(mèng)想加油課件
- 中日合同范本
- T-CARM 002-2023 康復(fù)醫(yī)院建設(shè)標(biāo)準(zhǔn)
- 《康復(fù)按摩知識(shí)》課件
- 申論詳解(PPT課件)
- 封條模板A4直接打印版
- 立式加工中心說明書
- 唐太宗李世民
- 作文紙格子信紙
- 第八版神經(jīng)病學(xué)配套課件-12-中樞神經(jīng)系統(tǒng)感染性疾病
評(píng)論
0/150
提交評(píng)論