亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

.NET的深復制方法(以C#語言為例)

2020-01-24 00:58:17
字體:
來源:轉載
供稿:網友

很多時候我們復制一個對象實例A到實例B,在用實例B去做其他事情的時候,會對實例B進行修改,為保證對B的修改不會影響到A的正常使用,就需要使用到深復制。

我在網上搜到一些深復制的方法,同時寫了幾組例子對這些方法進行測試。

我的操作系統版本為Win7旗艦版,.NET Framework版本是4.5

測試程序

我建了一個C#窗體應用程序(Winform),其主窗口FormMain的Load函數內容如下:

private void FormMain_Load(object sender, EventArgs e){ //測試1:深度復制 自定義類 try {  Console.WriteLine("=== 深度復制 自定義類 ===");  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.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(ex.ToString()); }

    //測試2:深度復制 可序列化的自定義類
   

 try {  Console.WriteLine("=== 深度復制 可序列化的自定義類 ===");  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", "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 ex) {  Console.WriteLine(ex.ToString()); }

    //測試3:深度復制 DataTable
  

 try {  Console.WriteLine("=== 深度復制 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.Rows.Add("3-1", "3-2", "3-3");  Console.WriteLine("=== 復制前 ===");  for (int i = 0; i < dtKirov.Columns.Count; i++)  {   Console.Write(dtKirov.Columns[i].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.Rows[i][j].ToString() + "/t");   }   Console.WriteLine();  }  Console.WriteLine();  DataTable dtDreadNought = (DataTable)DataManHelper.DeepCopyObject(dtKirov);  Console.WriteLine("=== 復制后 ===");  for (int i = 0; i < dtDreadNought.Columns.Count; i++)  {   Console.Write(dtDreadNought.Columns[i].ColumnName + "/t");  }  Console.WriteLine("/n-----------------");  for (int i = 0; i < dtDreadNought.Columns.Count; i++)  {   for (int j = 0; j < dtDreadNought.Rows.Count; j++)   {    Console.Write(dtDreadNought.Rows[i][j].ToString() + "/t");   }   Console.WriteLine();  }  Console.WriteLine(); } catch (Exception ex) {  Console.WriteLine(ex.ToString()); }

    //測試4:深度復制 TextBox
   

 try {  Console.WriteLine("=== 深度復制 TextBox ===");  txtTest.Text = "1234";  Console.WriteLine("復制前:" + txtTest.Text);  TextBox txtTmp = new TextBox();  txtTmp = (TextBox)DataManHelper.DeepCopyObject(txtTest);  Console.WriteLine("復制后:" + txtTmp.Text); } catch (Exception ex) {  Console.WriteLine(ex.ToString()); }

    //測試5:深度復制 DataGridView
 

 try {  Console.WriteLine("=== 深度復制 DataGridView ===");  DataGridView dgvTmp = new DataGridView();  dgvTmp = (DataGridView)DataManHelper.DeepCopyObject(dgvTest); } catch (Exception ex) {  Console.WriteLine(ex.ToString()); }}

其中txtTest是一個測試用的TextBox,dgvTmp是一個測試用的DataGridView,TestClass是一個自定義類,TestClassWithS是添加了Serializable特性的TestClass類,它們的具體實現如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DataCopyTest{ public class TestClass {  public int a;  public string b;  public string[] c;  public TestClass d;  public override string ToString()  {   string s = "a:" + a + "/n";   if (b != null)   {    s += "b:" + b + "/n";   }   if (c != null)   {    foreach (string tmps in c)    {     if (!string.IsNullOrWhiteSpace(tmps))     {      s += "c:" + tmps + "/n";     }    }   }   if (d != null)   {    s += d.ToString();   }   return s;  } } //支持序列化的TestClass [Serializable] public class TestClassWithS {  public int a;  public string b;  public string[] c;  public TestClassWithS d;  public override string ToString()  {   string s = "a:" + a + "/n";   if (b != null)   {    s += "b:" + b + "/n";   }   if (c != null)   {    foreach (string tmps in c)    {     if (!string.IsNullOrWhiteSpace(tmps))     {      s += "c:" + tmps + "/n";     }    }   }   if (d != null)   {    s += d.ToString();   }   return s;  } }}

我對每個搜來的深復制方法,都用了這五個類的實例進行深復制測試,這五個類的特征如下:

I、對自定義類TestClass進行深復制測試

II、對自定義類TestClassWithS進行深復制測試,TestClassWithS是添加了Serializable特性的TestClass類

III、對DataTable進行深復制測試

IV、對控件TextBox進行深復制測試

V、對控件DataGridView進行深復制測試

我們通過實現方法DataManHelper.DeepCopyObject來進行測試

測試深復制方法1

使用二進制流的序列化與反序列化深度復制對象

public static object DeepCopyObject(object obj){ BinaryFormatter Formatter = new BinaryFormatter(null,   new StreamingContext(StreamingContextStates.Clone)); MemoryStream stream = new MemoryStream(); Formatter.Serialize(stream, obj); stream.Position = 0; object clonedObj = Formatter.Deserialize(stream); stream.Close(); return clonedObj;}

五個場景的測試結果為:

I、觸發異常SerializationException,原因是該類不支持序列化

“System.Runtime.Serialization.SerializationException”類型的第一次機會異常在 mscorlib.dll 中發生
System.Runtime.Serialization.SerializationException: 程序集“DataCopyTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的類型“DataCopyTest.TestClass”未標記為可序列化。
   在 System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
   在 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, S“DataCopyTest.vshost.exe”(托管(v4.0.30319)): 已加載“C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll”
erializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 24
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 37
II、可正常復制 (√)

III、可正常復制 (√)

IV、觸發異常SerializationException,原因是該類不支持序列化

“System.Runtime.Serialization.SerializationException”類型的第一次機會異常在 mscorlib.dll 中發生
System.Runtime.Serialization.SerializationException: 程序集“System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中的類型“System.Windows.Forms.TextBox”未標記為可序列化。
   在 System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
   在 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 24
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 128
V、觸發異常SerializationException,原因是該類不支持序列化

“System.Runtime.Serialization.SerializationException”類型的第一次機會異常在 mscorlib.dll 中發生
System.Runtime.Serialization.SerializationException: 程序集“System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中的類型“System.Windows.Forms.DataGridView”未標記為可序列化。
   在 System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
   在 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 24
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 141
結論:利用序列化與反序列化到二進制流的方法深復制對象,只有在該對象支持Serializable特性時才可使用

測試深復制方法2

public static object DeepCopyObject(object obj){ Type t = obj.GetType(); PropertyInfo[] properties = t.GetProperties(); Object p = t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, obj, null); foreach (PropertyInfo pi in properties) {  if (pi.CanWrite)  {   object value = pi.GetValue(obj, null);   pi.SetValue(p, value, null);  } } return p;}

五個場景的測試結果為:

I、不會觸發異常,但結果完全錯誤

II、不會觸發異常,但結果完全錯誤

III、不會觸發異常,但結果完全錯誤

IV、Text字段賦值結果正確,但其他內容不能保證

V、觸發異常ArgumentOutOfRangeException、TargetInvocationException

“System.ArgumentOutOfRangeException”類型的第一次機會異常在 System.Windows.Forms.dll 中發生
“System.Reflection.TargetInvocationException”類型的第一次機會異常在 mscorlib.dll 中發生
System.Reflection.TargetInvocationException: 調用的目標發生了異常。 ---> System.ArgumentOutOfRangeException: 指定的參數已超出有效值的范圍。
參數名: value
   在 System.Windows.Forms.DataGridView.set_FirstDisplayedScrollingColumnIndex(Int32 value)
   --- 內部異常堆棧跟蹤的結尾 ---
   在 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, 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.RuntimePropertyInfo.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:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 29
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 141
結論:使用這種方法進行所謂深復制,完全是自尋死路!

測試深復制方法3

public static object DeepCopyObject(object obj){ if (obj != null) {  object result = Activator.CreateInstance(obj.GetType());  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.Add(DeepCopyObject(item));     }    }   }  }  return result; } else {  return null; }}

五個場景的測試結果為:

I、可正常復制(√)

II、可正常復制(√)

III、未觸發異常, 復制后DataTable無行列

IV、未觸發異常,Text字段未賦值

V、未觸發異常

結論:這個方法只適用于深復制具備簡單結構的類(如類中只有基礎字段、數組等),對于不支持序列化的對象也可以進行深復制。

測試深復制方法4

這段代碼來源同方法3

public static object DeepCopyObject(object obj){ if (obj == null)  return null; Type 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; 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 (FieldInfo 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");}

五個場景的測試結果為:

I、可正常復制(√)

II、可正常復制(√)

III、觸發異常MissingMethodException

“System.MissingMethodException”類型的第一次機會異常在 mscorlib.dll 中發生
System.MissingMethodException: 沒有為該對象定義無參數的構造函數。
   在 System.RuntimeTypeHandle.CreateInstance(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.CreateInstanceDefaultCtor(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:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 45
   在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 53
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 99
IV、未觸發異常,但Text字段也未賦值成功

V、觸發異常MissingMethodException

“System.MissingMethodException”類型的第一次機會異常在 mscorlib.dll 中發生
System.MissingMethodException: 沒有為該對象定義無參數的構造函數。
   在 System.RuntimeTypeHandle.CreateInstance(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.CreateInstanceDefaultCtor(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:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 45
   在 DataCopyTest.DataManHelper.DeepCopyObject(Object obj) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/DataManHelper.cs:行號 53
   在 DataCopyTest.FormMain.FormMain_Load(Object sender, EventArgs e) 位置 d:/MyPrograms/DataCopyTest/DataCopyTest/FormMain.cs:行號 141
結論:這個方法的作用類似方法3,只能深復制基本數據類型組成的類

具體問題具體分析

從上面的例子可以看出,想找一個放之四海而皆準的方式去深復制所有對象是很困難的。一些使用高級語言特性(反射)的深復制方法,即使可以在部分類上試用成功,也無法對所有的類都具備十足的把握。因此我認為應該采取下面的方式處理對象的深復制問題:

1、對于由基本數據類型組成的類,為之打上Serializable標簽,直接使用序列化與反序列化的方法進行深復制

2、其他較為復雜的類型如DataGridView,可根據自身情況寫一個方法進行深復制,之所以在這里說要根據自身情況寫方法,是因為在對很多類進行復制時,你只需要復制對你有用的屬性就行了。如TextBox控件中,只有Text一個屬性對你是有用的,如果你需要在復制后的對象中用到Readonly等屬性的值,那么在你自己實現的復制方法中,也加上對這些屬性的賦值即可。這樣做還有一個好處,就是方便進行一些定制化的開發。

如下面這段代碼,就是對DataGridView的一個近似的深復制,這段代碼將一個DataGridView(dgv)的內容復制到另一個DataGridView(dgvTmp)中,然后將dgvTmp傳遞給相關函數用于將DataGridView中的內容輸出到Excel文檔:

DataGridView dgvTmp = new DataGridView();dgvTmp.AllowUserToAddRows = false; //不允許用戶生成行,否則導出后會多出最后一行for (int i = 0; i < dgv.Columns.Count; i++){ dgvTmp.Columns.Add(dgv.Columns[i].Name, dgv.Columns[i].HeaderText); if (dgv.Columns[i].DefaultCellStyle.Format.Contains("N")) //使導出Excel文檔金額列可做SUM運算 { dgvTmp.Columns[i].DefaultCellStyle.Format = dgv.Columns[i].DefaultCellStyle.Format; } if (!dgv.Columns[i].Visible) { dgvTmp.Columns[i].Visible = false; }}for (int i = 0; i < dgv.Rows.Count; i++){ object[] objList = new object[dgv.Rows[i].Cells.Count]; for (int j = 0; j < objList.Length; j++) { if (dgvTmp.Columns[j].DefaultCellStyle.Format.Contains("N")) { objList[j] = dgv.Rows[i].Cells[j].Value; //使導出Excel文檔金額列可做SUM運算 } else { objList[j] = dgv.Rows[i].Cells[j].EditedFormattedValue; //數據字典按顯示文字導出 } } dgvTmp.Rows.Add(objList);}

這段代碼的特點如下:

1、DataGridView的屬性AllowUserToAddRows要設置成false,否則導出到Excel文檔后,會發現最后會多出一個空行。

2、我們在這里標記了那些列是隱藏列,這樣在后面的處理中,如果要刪除這些列,那刪除的也是dgvTmp的列而不是dgv的列,保護了原數據。

3、對于部分數據字典的翻譯,我們傳的不是Value而是EditedFormattedValue,這種方式直接使用了dgv在屏幕上顯示的翻譯后文字,而不是原來的數據字典值。

4、對于部分金額列,需要直接傳Value值,同時需要設置該列的DefaultCellStyle.Format,這樣可使得這些內容在之后輸出到Excel文檔后,可做求和運算(Excel中類似“12,345.67”字符串是不能做求和運算的)。 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
午夜精品一区二区三区在线| 久久夜色精品国产| 亚洲毛茸茸少妇高潮呻吟| 黑丝美女久久久| www.欧美视频| 亚洲第一页中文字幕| 91福利视频在线观看| 亚洲国产99精品国自产| 亚洲第一中文字幕在线观看| 亚洲 日韩 国产第一| 国产精品视频99| 91香蕉国产在线观看| 久久国产色av| 韩剧1988免费观看全集| 日韩精品视频在线免费观看| 久久久这里只有精品视频| 国产日本欧美在线观看| 91香蕉嫩草影院入口| 欧美丰满少妇xxxxx做受| 国产亚洲精品va在线观看| 色yeye香蕉凹凸一区二区av| 国产精品国产三级国产aⅴ9色| 欧美黑人一级爽快片淫片高清| 亚洲成年人在线播放| 日本精品免费一区二区三区| 日韩美女主播视频| 日韩av片永久免费网站| 亚洲欧美日韩精品久久奇米色影视| 日韩电影免费在线观看中文字幕| 欧美老少做受xxxx高潮| 成人黄色网免费| 欧美视频在线观看免费网址| 日韩中文字幕在线| 久久露脸国产精品| 成人春色激情网| 国产精品尤物福利片在线观看| 精品久久久久久久久久久久| 亚洲欧美精品suv| 国产精品久久97| 国产香蕉一区二区三区在线视频| 成人免费看黄网站| 性欧美视频videos6一9| 久久这里只有精品视频首页| 欧美日韩国产页| 久久久久女教师免费一区| 久热精品在线视频| 97超级碰碰碰久久久| 国产亚洲欧美另类中文| 黄色成人在线免费| 亚洲视频777| 亚洲成人动漫在线播放| 欧美一级免费看| 国产精品一区二区3区| 成人黄色午夜影院| 成人看片人aa| 成人xxxxx| 国模私拍视频一区| 日韩一级黄色av| 中文字幕在线精品| 色777狠狠综合秋免鲁丝| 亚洲男人天堂网站| 一区二区三区日韩在线| 亚洲xxxx18| 久久这里只有精品99| xxav国产精品美女主播| 欧美性极品xxxx做受| 日本一区二区不卡| 中文字幕国产精品| 成人国产精品久久久久久亚洲| 国产精品欧美激情在线播放| 中国人与牲禽动交精品| 亚洲网站在线播放| 欧美一级片久久久久久久| 日韩免费高清在线观看| 川上优av一区二区线观看| 欧美性猛交视频| 亚洲欧美另类中文字幕| 亚洲精品视频播放| 成人激情视频小说免费下载| 综合136福利视频在线| 91国内精品久久| 成人免费观看网址| 国产精品稀缺呦系列在线| 永久555www成人免费| 麻豆成人在线看| 国模极品一区二区三区| 国内久久久精品| 中文字幕欧美精品日韩中文字幕| 黄色精品一区二区| 久久久亚洲影院你懂的| 久久久免费观看| 欧美大荫蒂xxx| 亚洲一区二区黄| 正在播放欧美视频| 欧美日韩在线视频首页| 亚洲免费av片| 中文字幕久精品免费视频| 另类美女黄大片| 亲爱的老师9免费观看全集电视剧| 欧美日韩亚洲系列| 午夜精品久久久久久久久久久久| 国产一区二区三区中文| 国产精品久久久久91| 欧美视频第一页| 国产日韩欧美在线| 亚洲视频专区在线| 亚洲97在线观看| 欧美激情网友自拍| 亚洲国产精品久久久久| 国内精品模特av私拍在线观看| 日韩中文在线观看| 美乳少妇欧美精品| 国产精品亚洲综合天堂夜夜| 5566成人精品视频免费| 欧美日韩国产综合新一区| 亚洲国产精品视频在线观看| 亚洲在线第一页| 欧美日韩国产一区二区三区| 亚洲第一页中文字幕| 日本精品中文字幕| 91成人在线观看国产| 富二代精品短视频| 日韩在线免费av| 色99之美女主播在线视频| 欧美精品在线网站| 精品动漫一区二区| 欧美亚洲视频在线看网址| 国产91精品久久久久久久| 亚洲综合国产精品| 日韩电影中文字幕在线| 最近免费中文字幕视频2019| 欧美一区二区三区……| 热草久综合在线| 亚洲码在线观看| 国产一区二区久久精品| 91日本在线观看| 久久69精品久久久久久国产越南| 大量国产精品视频| 国产精品色悠悠| 日韩av片免费在线观看| 中文字幕亚洲色图| 成人福利网站在线观看| 精品国产31久久久久久| 日本午夜精品理论片a级appf发布| 孩xxxx性bbbb欧美| 欧美成人精品在线观看| 亚洲欧美精品伊人久久| 欧美激情亚洲自拍| 热re99久久精品国产66热| 2019最新中文字幕| 国产一区二区在线播放| 九九视频直播综合网| 亚洲一区二区三区视频| 亚洲欧美日韩区| 青草青草久热精品视频在线网站| 亚洲乱码国产乱码精品精| 欧美成人精品影院| 精品亚洲夜色av98在线观看| 一区二区亚洲精品国产| 少妇激情综合网| 亚洲一区二区中文| 亚洲免费视频网站| 最近2019年手机中文字幕| 久久久久久久久久久网站|