C# 分配给引用和内存后会发生什么?

C# 分配给引用和内存后会发生什么?,c#,binary-tree,reference-type,C#,Binary Tree,Reference Type,我遇到了一个Remove()函数,它对我来说似乎不合适。我们有两个变量obj1和obj2。他们都来自同一个班级 public class BinayTree<T> (){ public T value; public BinayTree<T> parent; public BinayTree<T> leftChild; public BinayTree<T> rightChild; } 会不会发生这种情况: 或者这个: 内存到

我遇到了一个
Remove()
函数,它对我来说似乎不合适。我们有两个变量
obj1
obj2
。他们都来自同一个班级

public class BinayTree<T> (){
  public T value;
  public BinayTree<T> parent;
  public BinayTree<T> leftChild;
  public BinayTree<T> rightChild;
}
会不会发生这种情况:

或者这个:


内存到底发生了什么呢?

因为它们是对象实例,所以它们是引用类型的。当你完成这项任务时:

obj1 = obj2;
变量
obj1
将引用
obj2
中的同一对象。它们在内存中引用相同的对象数据


以前在
obj1
中引用的对象现在已丢失,并将由垃圾收集器在内存中清理。

我希望这些数字能帮助您了解到底发生了什么

步骤1-初始化对象

var obj1 = new BinaryTree<int>();
obj1.Value = 123;

var obj2 = new BinartyTree<int>();
obj2.Value = 456;

步骤2-更改值

obj1 = obj2;
这里,我们正在更改
obj1
所指对象中属性的值

obj1.value = obj2.value;
obj1
字段的已更改:

 obj1                     obj2             
   |                        |              
   |                        |              
   |                        |              
   V                        V              
 _____________            _____________     
|   #333      |          |   #555      |  
|_____________|          |_____________|      
|             |          |             |    
| Value: 456  |          | Value: 456  |     
|             |          |             |     
|_____________|          |_____________| 

第3步-更改参考

obj1 = obj2;
这里,我们正在更改对
obj1
指向的对象的引用

 obj1                     obj2             
    \__                     |              
        \__                 |              
            \__             |              
                \__         V              
 _____________      \__   _____________     
|   #333      |       _\||   #555      |  
|_____________|          |_____________|      
|             |          |             |    
| Value: 456  |          | Value: 456  |     
|             |          |             |     
|_____________|          |_____________| 
我们没有更改任何对象的值。我们只是更改了
obj1
指向的对象

 obj1                     obj2             
    \__                     |              
        \__                 |              
            \__             |              
                \__         V              
 _____________      \__   _____________     
|   #333      |       _\||   #555      |  
|_____________|          |_____________|      
|             |          |             |    
| Value: 456  |          | Value: 456  |     
|             |          |             |     
|_____________|          |_____________| 

根据您的问题,我可以看出您希望代码将这两个对象隐式地链接到彼此

这样想:如果您的期望是这样的话,那么我们就不需要像
BinaryTree
这样的类,这些类具有对其他
BinaryTree
对象的内部引用

示例类的存在证明您的期望并非如此


编辑

我的示例假设
BinaryTree
中的
T
值类型。如果这是一个引用类型(例如,您创建的自定义类),那么步骤2会变得更加复杂。我不认为我能用我有限的艺术技巧画出那样的画

在无意冒犯的情况下,您对引用类型赋值基础知识的掌握与您发布的示例代码的复杂性之间存在明显的差异


您目前正在努力学习引用类型变量的基础知识。我建议在尝试使用引用类型参数处理泛型类之前,先复习一下基础知识;因为在不了解引用类型分配如何工作的情况下,这将变得非常复杂。

假设
T
是一个引用类型,我将确切地告诉您发生了什么

本来

第一行之后:

第二行之后:

基本上发生的是:

  • obj1
    obj2
    现在指的是同一个对象
  • 原始由
    obj1
    引用的
    BinaryTree
    对象变得不可访问
  • T
    (以前称为
    obj1.value
    )的对象变得不可访问

我不明白这里有什么问题。内存中的
删除
有什么问题,变量
obj1
现在将指向与变量
obj2
相同的
BinayTree
实例。第一个语句的效果取决于它是引用类型还是值类型。如果它是值类型,则将值从object2复制到object1,然后object1指向object2。如果内存中没有指向object1所指向的原始位置的对象,则GC将回收该内存。如果我们希望obj1获得obj2的值,并希望删除obj2,那么我们需要这样说,对吗<代码>obj1.value=obj2.value;obj2=null因此,在第一行obj1指向与obj2相同的对象之后,以及在第二行obj2不指向之后anywhere@NikolaiKolev:如果我理解正确;是的,这是正确的。然而,你的措辞常常模棱两可。例如,当您说“delete obj2”时,您可能是从内存中引用(a)删除obj2所引用的对象(b)删除obj2中指向该特定对象的引用,或(c)以某种方式暗示可以删除变量本身。在语义上,(c)是最正确的,(a)是第二正确的(英语中的语义);但你可能打算谈论(b)。这种模糊性在问题的可读性方面造成了很多问题。