. NET deep Copy Method (example of C # language) _c# tutorial

Source: Internet
Author: User
Tags mscorlib reflection serialization stack trace

A lot of times we copy an object instance A to instance B, and when we do something with instance B, we modify instance B to make sure that the modification to B does not affect the normal use of a, you need to use a deep copy.

I found some deep copy methods on the Internet and wrote several sets of examples to test these methods.

My operating system version is Win7 flagship, the. NET Framework version is 4.5

Test program

I built a C # form application (Winform) whose main window formmain the load function as follows:

private void Formmain_load (object sender, EventArgs e)
{
 //test 1: Deep copy custom class
 try
 {
  Console.WriteLine ("= = = Deep copy of the custom class = =");
  TestClass test1 = new TestClass ();
  test1.a = ten;
  test1.b = "Hello world!";
  test1.c = new string[] {"x", "Y", "Z"};
  TestClass test2 = new TestClass ();
  test2.a = one;
  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 ());
 }

Test 2: Deep copy serializable custom classes

 Try
 {
  Console.WriteLine ("= = = = (= = =") (custom class = = "deep copy serializable)
  Testclasswiths test1 = new Testclasswiths ();
  test1.a = ten;
  test1.b = "Hello world!";
  test1.c = new string[] {"x", "Y", "Z"};
  Testclasswiths test2 = new Testclasswiths ();
  test2.a = one;
  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 ());
 }

Test 3: Deep copy DataTable

 try {Console.WriteLine ("= = = Deep copy 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 ("= = = = after the copy = = ="); 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 (); The catch (Exception ex) {Console.WriteLine (ex).
 ToString ());
 }

Test 4: Deep copy TextBox

 Try
 {
  Console.WriteLine ("= = = Deep copy TextBox = = =");
  Txttest.text = "1234";
  Console.WriteLine ("Before copying:" + txttest.text);
  TextBox txttmp = new TextBox ();
  Txttmp = (TextBox) datamanhelper.deepcopyobject (txttest);
  Console.WriteLine ("After copy:" + Txttmp.text);
 }
 catch (Exception ex)
 {
  Console.WriteLine (ex. ToString ());
 }

Test 5: Deep copy DataGridView

 Try
 {
  Console.WriteLine ("= = = Deep copy DataGridView = =)";
  DataGridView dgvtmp = new DataGridView ();
  Dgvtmp = (DataGridView) datamanhelper.deepcopyobject (dgvtest);
 }
 catch (Exception ex)
 {
  Console.WriteLine (ex. ToString ());
 }

Where Txttest is a test textbox,dgvtmp is a test datagridview,testclass is a custom class, Testclasswiths is a serializable class with TestClass attributes added , their specific implementation is as follows:

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;
  }///support serialization of 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 used each of these five class instances for deep copy tests on each of the deep copy methods, and the five classes were characterized as follows:

I, deep copy test for custom class TestClass

II, a deep copy test of the custom class Testclasswiths, Testclasswiths is a TestClass class that adds the serializable attribute

III. Deep copy test for DataTable

IV, a deep copy test of the control textbox

V, deep Copy test for control DataGridView

We test by implementing the method Datamanhelper.deepcopyobject

Test deep Copy Method 1

Using binary streams for serialization and deserialization of deep copy objects

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;
}

The test results for five scenarios are:

I, triggering an exception serializationexception because the class does not support serialization

The first chance exception for the "System.Runtime.Serialization.SerializationException" type occurs in mscorlib.dll


System.Runtime.Serialization.SerializationException: Assembly "Datacopytest, version=1.0.0.0, Culture=neutral, The type "Datacopytest.testclass" in Publickeytoken=null is not marked as serializable.


In System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (RuntimeType type)


In System.Runtime.Serialization.FormatterServices.GetSerializableMembers (type type, StreamingContext context)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo ()


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, Serializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, S "DataCopyTest.vshost.exe" (Managed (v4.0.30319)): Loaded "C:\Windows\Microsoft.Net\assembly\GAC_ Msil\system.numerics\v4.0_4.0.0.0__b77a5c561934e089\system.numerics.dll "


Erializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (Object graph, header[] inheaders, __ BinaryWriter Serwriter, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph, header[] headers, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 24


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 37


II, can be normal replication (√)

III, can be normal replication (√)

IV, triggering an exception serializationexception because the class does not support serialization

The first chance exception for the "System.Runtime.Serialization.SerializationException" type occurs in mscorlib.dll


System.Runtime.Serialization.SerializationException: Assembly "System.Windows.Forms, version=4.0.0.0, Culture=neutral, The type "System.Windows.Forms.TextBox" in publickeytoken=b77a5c561934e089 is not marked as serializable.


In System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (RuntimeType type)


In System.Runtime.Serialization.FormatterServices.GetSerializableMembers (type type, StreamingContext context)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo ()


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, Serializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, Serializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (Object graph, header[] inheaders, __ BinaryWriter Serwriter, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph, header[] headers, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 24


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 128


V, triggering an exception serializationexception because the class does not support serialization

The first chance exception for the "System.Runtime.Serialization.SerializationException" type occurs in mscorlib.dll


System.Runtime.Serialization.SerializationException: Assembly "System.Windows.Forms, version=4.0.0.0, Culture=neutral, The type "System.Windows.Forms.DataGridView" in publickeytoken=b77a5c561934e089 is not marked as serializable.


In System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (RuntimeType type)


In System.Runtime.Serialization.FormatterServices.GetSerializableMembers (type type, StreamingContext context)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo ()


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, Serializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (Object obj, isurrogateselector SurrogateSelector, StreamingContext context, Serobjectinfoinit Serobjectinfoinit, Iformatterconverter Converter, Objectwriter Objectwriter, Serializationbinder Binder)


In System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (Object graph, header[] inheaders, __ BinaryWriter Serwriter, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph, header[] headers, Boolean Fcheck)


In System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (Stream serializationstream, Object Graph


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 24


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 141


Conclusion: By using serialization and deserialization to binary stream, the object is deeply copied and can only be used if the object supports serializable attributes.

Test deep Copy Method 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;
}

The test results for five scenarios are:

I, does not trigger an exception, but the result is completely wrong

II, no exception is fired, but the result is completely wrong

III, does not trigger an exception, but the result is completely wrong

IV, Text field assignment is correct, but other content is not guaranteed

V, triggering abnormal argumentoutofrangeexception, targetinvocationexception

The first chance exception for the "System.ArgumentOutOfRangeException" type occurs in System.Windows.Forms.dll


The first chance exception for the "System.Reflection.TargetInvocationException" type occurs in mscorlib.dll


System.Reflection.TargetInvocationException: The target of the call has an exception. ---> system.argumentoutofrangeexception: The specified parameter has exceeded the range of valid values.


Parameter name: value


In System.Windows.Forms.DataGridView.set_FirstDisplayedScrollingColumnIndex (Int32 value)


---the end of the inner exception stack trace---


In System.RuntimeMethodHandle.InvokeMethod (Object target, object[] arguments, Signature Sig, Boolean constructor)


In System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal (Object obj, object[] parameters, object[] arguments)


In System.Reflection.RuntimeMethodInfo.Invoke (Object obj, BindingFlags invokeattr, Binder Binder, object[] parameters, CultureInfo culture)


In System.Reflection.RuntimePropertyInfo.SetValue (object obj, Object value, BindingFlags invokeattr, Binder Binder, object[] Index, CultureInfo culture)


In System.Reflection.RuntimePropertyInfo.SetValue (object obj, object value, object[] index)


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 29


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 141


Conclusion: The use of this method for the so-called deep copy, is completely suicidal road!

Test deep Copy Method 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;
 }
}

The test results for five scenarios are:

I, can be normal replication (√)

II, can be normal replication (√)

III, did not trigger the exception, the DataTable after replication no row

IV, no exception triggered, text field not assigned

V, no exception fired

Conclusion: This method is only suitable for deep copying of classes with simple structures (such as only the underlying fields, arrays, etc.) in the class, and can be deeply replicated for objects that do not support serialization.

Test deep Copy Method 4

This code source is the same as Method 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 ("UnknownType ");

 }

The test results for five scenarios are:

I, can be normal replication (√)

II, can be normal replication (√)

III, triggering abnormal missingmethodexception

The first chance exception for the "System.MissingMethodException" type occurs in mscorlib.dll


System.MissingMethodException: There is no parameterless constructor defined for this object.


In System.RuntimeTypeHandle.CreateInstance (RuntimeType type, Boolean publiconly, Boolean NoCheck, boolean& Canbecached, runtimemethodhandleinternal& ctor, boolean& Bneedsecuritycheck)


In System.RuntimeType.CreateInstanceSlow (Boolean publiconly, Boolean Skipcheckthis, Boolean FillCache, StackCrawlMark & Stackmark)


In System.RuntimeType.CreateInstanceDefaultCtor (Boolean publiconly, Boolean Skipcheckthis, Boolean FillCache, stackcrawlmark& Stackmark)


In System.Activator.CreateInstance (type type, Boolean nonpublic)


In System.Activator.CreateInstance (type type)


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 45


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 53


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 99


IV, no exception was fired, but the text field has not been assigned a value successfully

V, triggering exception missingmethodexception

The first chance exception for the "System.MissingMethodException" type occurs in mscorlib.dll


System.MissingMethodException: There is no parameterless constructor defined for this object.


In System.RuntimeTypeHandle.CreateInstance (RuntimeType type, Boolean publiconly, Boolean NoCheck, boolean& Canbecached, runtimemethodhandleinternal& ctor, boolean& Bneedsecuritycheck)


In System.RuntimeType.CreateInstanceSlow (Boolean publiconly, Boolean Skipcheckthis, Boolean FillCache, StackCrawlMark & Stackmark)


In System.RuntimeType.CreateInstanceDefaultCtor (Boolean publiconly, Boolean Skipcheckthis, Boolean FillCache, stackcrawlmark& Stackmark)


In System.Activator.CreateInstance (type type, Boolean nonpublic)


In System.Activator.CreateInstance (type type)


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 45


In DataCopyTest.DataManHelper.DeepCopyObject (Object obj) position d:\MyPrograms\DataCopyTest\DataCopyTest\ DataManHelper.cs: Line No. 53


In the position of DataCopyTest.FormMain.FormMain_Load (Object sender, EventArgs e) d:\MyPrograms\DataCopyTest\DataCopyTest\ FormMain.cs: Line No. 141


Conclusion: This method works like Method 3, and can only deeply replicate classes consisting of basic data types

Specific analysis of specific problems

As can be seen from the example above, it is difficult to find a universal way to copy all the objects deeply. Some deep copy methods that use advanced language features (reflection) cannot be fully grasped by all classes, even if they can be tried successfully on some classes. So I think we should take the following approach to the deep replication of objects:

1, for the class composed of basic data types, for which the serializable tag, directly using serialization and deserialization of the method for deep replication

2, other more complex types such as DataGridView, according to their own situation to write a method for deep copy, said here to write the method according to their own situation, because in the replication of many classes, you only need to copy the attributes that are useful to you. For example, in a TextBox control, only text a property is useful to you, and if you need to use the values of attributes such as ReadOnly in the copied object, then in the copy method that you implement, add the assignment to those attributes. This also has the advantage, is facilitates to carry on some custom development.

The

, as in the following code, is an approximate deep copy of DataGridView, which copies the contents of a DataGridView (DGV) to another DataGridView (dgvtmp). Dgvtmp is then passed to the correlation function to output the contents of the DataGridView to an Excel document:

DataGridView dgvtmp = new DataGridView ();
Dgvtmp.allowusertoaddrows = false; The user is not allowed to produce rows, otherwise the last line for
(int i = 0; i < DGV) is exported. Columns.count; i++)
{
 dgvTmp.Columns.Add (DGV). Columns[i]. Name, DGV. Columns[i]. HeaderText);
 if (DGV. Columns[i]. DefaultCellStyle.Format.Contains ("N"))//Enables the export of Excel document amount columns to do the sum operation
 {
 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; Make the export Excel Document Amount column available for sum operations
 }
 else
 {
 Objlist[j] = DGV. Rows[i]. CELLS[J]. Editedformattedvalue; The data dictionary is exported by display text
 }
 dgvTmp.Rows.Add (objlist);

The features of this code are as follows:

1, DataGridView Property allowusertoaddrows to set to false, otherwise exported to an Excel document, you will find that the end of a more empty line.

2, we are here to mark those columns are hidden columns, so in the subsequent processing, if you want to delete these columns, then delete the Dgvtmp column rather than the DGV column, protect the original data.

3, for some of the data dictionary translation, we preach not value but editedformattedvalue, this way directly using the DGV on the screen to display the translated text, rather than the original data dictionary values.

4, for part of the amount of the column, you need to pass the value directly, and you need to set the Defaultcellstyle.format of the column, so that these content after the output to Excel document, you can do the sum operation (Excel, similar to "12,345.67" A string is not able to do a sum operation.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.