浅拷贝或深拷贝?
对于将一个对象复制到另一个中的这两种方法,我有点新意。 我很困惑,无法发现深拷贝和浅拷贝之间的主要区别..我已经通过了很多关于这个的理论,但是我需要用适当的例子来解释..我有一个程序,我将一个对象拷贝到另一个。 - >
class A
{
public int a = 0;
public void display()
{
Console.WriteLine("The value of a is " + a);
}
}
class Program
{
static void Main(string[] args)
{
A ob1 = new A();
ob1.a = 10;
ob1.display();
A ob2 = new A();
ob2 = ob1;
ob2.display();
Console.Read();
}
}
这是浅拷贝还是深拷贝? 任何人都可以请原因提供答案。 如果它是一个深层复制,那么请提供该程序的浅拷贝代码,以完成对象拷贝的相同工作,反之亦然。
如果上面是浅拷贝,那么即使这应该是浅拷贝 - >
A ob1 = new A();
ob1.a = 10;
ob1.display();
A ob2 = ob1;
ob2.a = 444;
ob1.display();
从这里的链接
浅拷贝重复尽可能少。 集合的浅表副本是集合结构的副本,而不是元素。 有了浅拷贝,两个集合现在可以共享单个元素。
深拷贝复制一切。 集合的深层副本是两个集合,其中原始集合中的所有元素都是重复的。
你的例子是创建一个浅拷贝。
A ob1 = new A();
ob1.a = 10;
A ob2 = new A();
ob2 = ob1;
ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 5.
深层复制将是 -
A ob1 = new A();
ob1.a = 10;
A ob2 = new A();
ob2.a = ob1.a;
ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 10.
在我看来,它不是一个严格的浅拷贝或深拷贝。 如果我必须定义它,我会说浅拷贝。
ob2 = ob1; 此代码创建两个引用同一个对象的对象引用。 因此,通过ob1所做的对对象的任何更改都会反映在ob2的后续使用中。
MSDN示例最好解释浅拷贝,深拷贝和简单类拷贝的差异。
using System;
public class IdInfo
{
public int IdNumber;
public IdInfo(int IdNumber)
{
this.IdNumber = IdNumber;
}
}
public class Person
{
public int Age;
public string Name;
public IdInfo IdInfo;
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
public Person DeepCopy()
{
Person other = (Person)this.MemberwiseClone();
other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
other.Name = String.Copy(this.Name);
return other;
}
}
public class Example
{
public static void Main()
{
// Create an instance of Person and assign values to its fields.
Person p1 = new Person();
p1.Age = 42;
p1.Name = "Sam";
p1.IdInfo = new IdInfo(6565);
// Perform a shallow copy of p1 and assign it to p2.
Person p2 = (Person)p1.ShallowCopy();
// Display values of p1, p2
Console.WriteLine("Original values of p1 and p2:");
Console.WriteLine(" p1 instance values: ");
DisplayValues(p1);
Console.WriteLine(" p2 instance values:");
DisplayValues(p2);
// Change the value of p1 properties and display the values of p1 and p2.
p1.Age = 32;
p1.Name = "Frank";
p1.IdInfo.IdNumber = 7878;
Console.WriteLine("nValues of p1 and p2 after changes to p1:");
Console.WriteLine(" p1 instance values: ");
DisplayValues(p1);
Console.WriteLine(" p2 instance values:");
DisplayValues(p2);
// Make a deep copy of p1 and assign it to p3.
Person p3 = p1.DeepCopy();
// Change the members of the p1 class to new values to show the deep copy.
p1.Name = "George";
p1.Age = 39;
p1.IdInfo.IdNumber = 8641;
Console.WriteLine("nValues of p1 and p3 after changes to p1:");
Console.WriteLine(" p1 instance values: ");
DisplayValues(p1);
Console.WriteLine(" p3 instance values:");
DisplayValues(p3);
// Make an equal of p1 and assign it to p4.
Person p4 = new Person();
p4 = p1;
// Change the members of the p1 class to new values to show the equal copy.
p1.Name = "Will";
p1.Age = 30;
p1.IdInfo.IdNumber = 8484;
Console.WriteLine("nValues of p1 and p4 after changes to p1:");
Console.WriteLine(" p1 instance values: ");
DisplayValues(p1);
Console.WriteLine(" p4 instance values:");
DisplayValues(p4);
}
public static void DisplayValues(Person p)
{
Console.WriteLine(" Name: {0:s}, Age: {1:d}", p.Name, p.Age);
Console.WriteLine(" Value: {0:d}", p.IdInfo.IdNumber);
}
}
结果如下:
Original values of p1 and p2: p1 instance values:
Name: Sam, Age: 42
Value: 6565 p2 instance values:
Name: Sam, Age: 42
Value: 6565
Values of p1 and p2 after changes to p1: p1 instance values:
Name: Frank, Age: 32
Value: 7878 p2 instance values:
Name: Sam, Age: 42
Value: 7878
Values of p1 and p3 after changes to p1: p1 instance values:
Name: George, Age: 39
Value: 8641 p3 instance values:
Name: Frank, Age: 32
Value: 7878
Values of p1 and p4 after changes to p1: p1 instance values:
Name: Will, Age: 30
Value: 8484 p4 instance values:
Name: Will, Age: 30
Value: 8484
这既不是简单的也不是深层的复制,这是一个参考copy.let我解释说:有两种类型的变量:值类型和引用类型。
值类型是计算机内存中(名称)的位置,用于保存变量的实际值。 例如:int是一个值类型,所以当你写下这行代码:
int MyInt = 5;
当这行代码执行时,运行时会在RAM中找到一个位置,并在其中写入值5。 所以如果您搜索该位置,您会发现实际值为5。
引用类型 - 相反 - 是内存中的一个(命名)位置,它实际上并不保存变量的值,而是保存该值存在的位置。 作为例子,假设你编写了下面的代码:
MyClass myObject = new MyClass();
发生的事情是虚拟机(运行时):1-查找并在内存中查找可用位置,创建一个MyClass类的实例。 可以说该对象的位置恰好在RAM中的字节#AA3D2处。
2-在内存中查找位置并创建MyClass类型的引用(引用是指向内存中某个位置的“箭头”),将其命名为“myObject”并将值AA3D2存储在其中。
现在,如果您查看“myObject”变量,您将发现不是类实例,但您会发现AA3D2,它表示存放该类实例的内存位置。
现在让我们来看看给定OP的代码:
A ob1 = new A();
这将创建一个名为ob1的变量,创建A类的实例并将该类的位置存储在ob1中
ob1.a = 10;
ob1.display();
这将改变A类内部的变量a。 然后调用display()方法
A ob2 = new A();
在这里它创建一个名为ob2的变量,创建类A的一个实例并将其位置分配给ob2。
现在你在内存中有2个A类实例和2个变量,每个指向它们中的一个。 现在这里是有趣的部分:ob2 = ob1;
变量ob2被分配变量ob1的值。 因为ob1包含A的第一个实例的内存位置,现在ob1和ob2都指向内存中的相同位置。 用其中一种做任何事情都与另一种做得相同。
ob2 = ob1表示您正在复制参考。
链接地址: http://www.djcxy.com/p/13933.html