使一个类的实例与另一个相等。 – 如何取消?

我有:

instance1 = instance2; 

如何将它们彼此断开,以便改变一个不会影响另一个?

编辑:我希望他们引用相同的对象(所以我不能克隆),后来 – 不是。 但是我仍然想要这个类的两个实例 – 所以我不能’空’它们。

谢谢

编辑:

 myclass a = new myclass(); a.integer = 1; myclass b = new myclass(); b.integer = 2; a = b; //All changes to one will affect the other, Which is what I want. // //Now I want 'a' to point to something else than 'b'. and I'm missing the code //so that the next line will not affect 'b'. a.integer = 1; Text = b.integer.ToString(); //I need b.integer to still be = 2, it's not. 

附:

 class myclass { public int integer; } 

编辑:

就是答案:@ispiro但是当你说a.integer = 1时你没有改变指针,你就是跟着指针并改变它末尾的值。 – 戴维8

我曾经以为改变’a’和’a.integer’都是相同的,因为改变它们会改变指针 – ‘a’或不会改变指针。 但实际上:第一个没有,第二个没有。

感谢大家。

所以在上面的例子中,如果我添加:

 a = c;// where c is another instance of 'myclass'. 

它将’a’改为指向除’b’之外的其他地方。 但:

 a.integer = 1; 

没有。

你的代码:

 myclass a = new myclass(); a.integer = 1; myclass b = new myclass(); b.integer = 2; a = b; //here I need code to disconnect them a.integer = 1; Text = b.integer.ToString(); //I need b.integer to still be = 2 

在此处输入图像描述

如果你留下参考:

 myclass a = new myclass(); a.integer = 1; myclass b = new myclass(); b.integer = 2; var c = a; //Keep the old a around a = b; //here I need code to disconnect them a = c; //Restore it. a.integer = 1; Text = b.integer.ToString(); //It's still 2 now. 

在此处输入图像描述

变量是对象的标签,而不是对象本身。 在您的情况下,原始a不再具有对它的引用,因此即使它存在,也无法访问它。 (只要垃圾收集器绕过去除它除非有其它引用它就会停止存在)

如果有帮助,可以这样想,当你说a = ba = new myclass()你正在移动a指向的行。 当你说a.integer = 1. 有点像跟着a指向的行,然后改变目的地。

假设你在一张纸上写下“1600宾夕法尼亚大道”。 那个地址指的是一所房子,实际上是白宫。

假设你在第二张纸上写下“1600宾夕法尼亚大道”。 该地址指的是与第一张纸相同的房屋。

你无能为力地改变这两个地址指的是同一个房子的事实。 你可以改变其中一张纸说“123芝麻街”,然后他们不再提到同一所房子,但这并没有改变关于白宫的事实,这改变了关于一张纸的事实。

如果你然后把白宫涂成蓝色,你仍然没有改变任何一张纸; 现在两个都是指一个蓝色的房子。

你能更详细地解释一下你在这里做的是什么吗? 你的问题很混乱。

我想我会根据你的评论更好地理解你在说什么。

答案非常简单。

这段代码:

 instance1 = instance2; 

不以任何方式链接instance1和instance2,除了它们指向同一个事实。 您始终可以重新指向任一变量(包括“取消它们”)而不会影响另一个变量。 将实例设置为null不会更改对象,只会使其停止指向内存中的对象。

从本质上讲,问题的前提是不准确的。 这里没有问题需要解决。

要点理解:变量instance1和instance2只是将对象的位置存储在内存中,而不是实际的对象。 如果您想操纵实际对象,则可以在该对象上使用方法或属性,例如:

 instance1.ChangeColor; // call the ChangeColor method on the object pointed to by instance1. 

更新:

假设a和b是索引卡片,其中包含可以容纳号码的邮箱地址。 这是您的代码正在进行的播放

 //create a mailbox (call it X) and write the address on index card A myclass a = new myclass(); //put the number 1 in the mailbox at the address written on index card A (currently x) a.integer = 1; //mailbox x now contains 1 //create ANOTHER mailbox (call it Y) and write the address on index card B myclass b = new myclass(); //put the number 2 in the mailbox at the address written on index card B (currently Y) b.integer = 2; //mailbox y now contains 2 // change the address on index card A to the address from card B (currently Y) a = b; //both cards now have the address of mailbox Y (which contains 2) written on them. // if you want a to go back to having the address of mailbox X, you are // out of luck because you don't have it written down on any of your cards anymore. //put the number 1 in the mailbox at the address pointed to on Card A (Currently Y) a.integer = 1; //mailbox Y now contains 1 //Set text to the number from the mailbox at the address on card B (currently Y) Text = b.integer.ToString(); 

为相关类编写一个复制构造函数,并将其中一个引用指向通过复制构造函数创建的新实例。

 MyClass instance1 = new MyClass(); MyClass instance2 = new MyClass(); instance1 = instance2; instance1 = null; //does not affect instance2. 

目前还不清楚你想做什么。 显然,如果设置instance1 = null ,则引用将不相同。 你问的是如何制作一份深拷贝?

您可能想要查看ICloneable接口。 您必须编写将一个实例的属性复制到另一个实例的代码。

或者,您可以重载=运算符。 或者创建一个可以调用的构造函数:

 MyClass instance2 = new MyClass(instance1); 

您需要一种克隆实例的方法(创建实例的副本)。

例如,在您的class级中:

 public MyClass(MyClass copy) { // ...copy all attributes, be careful with reference variables } 

然后你可以做以下事情:

 instance1 = new MyClass(instance2); 

它们都具有完全相同的属性和属性(如果您正确实现了复制构造函数),但修改一个不会影响另一个。

您的类可以是结构而不是使它成为值类型吗?

 public void Main() { MyObj a = new MyObj{ integer= 1}; MyObj b = a; Console.WriteLine(a.integer); //1 Console.WriteLine(b.integer);//1 b.integeter = 42; Console.WriteLine(a.integer);//1 Console.WriteLine(b.integer);//42 } public struct MyObj { public int integer{get; set;} } 

我建议将类类型的字段和变量视为持有“实例ID”是最有帮助的。 有些人认为它们是指针,但这是一个实现细节。 要实现的基本要点是,如果Foo是类类型Bar的变量,则语句“Foo.Boz()”不会指示编译器以任何方式改变Foo; 它指示编译器查找存储在Foo中的实例id引用的对象(该对象必须是Bar类型),并在该对象上运行Boz方法。 实例id本身可以完成很少的操作,而不是在由此引用的对象上:

  1. 实例id可以从一个变量或字段复制到另一个变量或字段。
  2. 实例id可以通过值传递给方法或属性
  3. 可以通过引用方法或属性来传递实例ID
  4. 实例id可以与另一个进行比较(不需要查看id引用的对象 – 只是id本身)

如果Biff和Baff是相同的实例id,那么对Biff引用的对象所做的操作将影响Baff引用的对象,因为它们是同一个对象(但是这样的动作实际上不会影响Biff和Baff本身,这将是仍然保持与以前相同的实例ID)。 如果有人希望Biff引用一个类似于Baff引用的对象,但有一些区别,那么必须创建一个类似于Biff和Baff所引用的对象的新对象,存入Biff的id新对象,然后修改该对象,使其与Baff指向的方式不同。

顺便提一下,除了支持类类型之外,.net还支持值类型(例如Integer或Double等基元,以及结构)。 与类类型不同,值类型的变量和字段是不相交的; 改变一个不会影响任何其他。 在许多情况下,值类型可以更容易地隔离数据依赖性。 然而,重要的是要注意,尽管能够在不影响任何其他值的情况下对一个值类型变量或字段进行更改是有用的,但是在更改值类型实体的一部分时(例如,结构),请注意,在某些情况下,.net将默默地制作值类型实体的副本,然后对副本进行操作。