如果我有这样的代码
val i = vec2t(1, 1) // Vec2t<Int> inferred from arguments type Int
println(i.size) // 8
val d = vec2t(1.0, 1.0) // the same but it's Vec2t<Double> this time
println(d.size) // 16
当我更改p2的值时,它也会改变p1的值,当我更改Object p3的值时,我得到相同的结果。我的问题是,如果两个逻辑都做同样的事情,那么分配和使用class Student
{
public string RollID { get; set; }
}
class Person
{
public Student student { get; set; }
public string Address { get; set; }
public string Name { get; set; }
public Person Clone()
{
return (Person)this.MemberwiseClone();
}
}
class Client
{
static void Main()
{
Student s1 = new Student();
s1.RollID = "151";
Person p1 = new Person();
p1.Address = "bombay";
p1.Name = "foo";
p1.student = s1;
Person p2 = p1.Clone();
p2.student.RollID = "1558";
Person p3 = p1;
p3.student.RollID = "454";
}
}
方法之间的真正区别是什么。如果我使用MemberwiseClone()
方法,还有其他优势吗?
答案 0 :(得分:4)
这里的问题是你做了很深的&#34;在浅拷贝上更新。如果你改变了p2.Address,它不会影响p1.Address;但如果更改p3.Address,它将更改影响p1.Address。
但是由于p1和p2共享对单个学生的引用,因此更改RollId会影响每个人。
Variable P1 ----> <PERSON OBJECT 1>
| .Address = 123 Elm St.
Variable P3 ----> |
| .Student ----> <STUDENT OBJECT 1>
|_______________ |
| .RollId // one value for all
Variable P2 ----> <PERSON OBJECT 2> |
| .Address = ... |
| .Student ----> |_________________
|_______________
答案 1 :(得分:2)
C#类由ref&#34;处理#34;默认情况下。这意味着当你将某个东西分配给另一个时,如果它是一个类而不是一个结构,你只需将指针指向新对象,而新对象就在内存中的两个句柄的同一位置。另一方面,您可以复制一个类。当你成员克隆某些东西时,你会创建一个新的对象,在内存中占据另一个位置。
现在这个Object.MemberwiseClone()
方法是一个浅复制函数,只复制其中的类和结构,并且该类中的类将由ref保存。请参阅this。
要深层复制某些类,您需要特别针对该类实现它,或者您可以找到使用反射写的通用类,这有点慢。
答案 2 :(得分:2)
MemberwiseClone方法通过创建新对象,然后将当前对象的非静态字段复制到新对象来创建浅表副本。如果字段是值类型,则执行字段的逐位复制。如果字段是引用类型,则复制引用但不引用引用的对象;因此,原始对象及其克隆引用相同的对象。
https://msdn.microsoft.com/en-us/library/system.object.memberwiseclone(v=vs.85).aspx
有两种克隆:浅克隆和深克隆。
在浅层克隆中,副本中的任何引用值都指向与原始对象中相同的对象。 在深度克隆中,新对象的引用值设置为新对象。 要使深度克隆实现ICloneable接口,请返回一个New Person对象。