c#引用类型按引用-地址到地址?
如果我通过引用传递引用类型,试图理解到底发生了什么。我是这样理解的: 所以我有一个类Foo,它表示一个引用类型c#引用类型按引用-地址到地址?,c#,pointers,reference,pass-by-reference,C#,Pointers,Reference,Pass By Reference,如果我通过引用传递引用类型,试图理解到底发生了什么。我是这样理解的: 所以我有一个类Foo,它表示一个引用类型 class Foo{ //Foo-stuff here } 就在这里 Foo f = new Foo(); Foo f(在堆栈上创建)保存实际对象的地址/引用,该对象在调用new Foo()时在堆中创建 所以f实际上包含类似0x2A53BC 如果我调用这样做的方法 void Test(Foo g) { g = null; } 我只需传递“地址变量/参考变量”的地址f。因此g实际上
class Foo{ //Foo-stuff here }
就在这里
Foo f = new Foo();
Foo f
(在堆栈上创建)保存实际对象的地址/引用,该对象在调用new Foo()时在堆中创建
所以f
实际上包含类似0x2A53BC
如果我调用这样做的方法
void Test(Foo g) { g = null; }
我只需传递“地址变量/参考变量”的地址f
。因此g
实际上指向堆栈中的f
,而不是堆中的实际对象。因此,我可以通过f
更改堆中Foo对象的属性,因为我有f
的地址,我可以通过f
访问Foo,但是设置g=null
只会杀死堆栈中f
变量的地址,而不是堆中对象本身的引用
但是有了这个
无效测试(ref Foo g){g=null;}
我实际上是在使用堆中那个Foo对象的真实地址,所以使用0x2A53BC
。这意味着,我可以通过设置g=null
是这样吗?多谢各位
我只需传递“地址变量/参考变量”的地址f
。因此g
实际上指向堆栈中的f
,而不是堆中的实际对象
事实上你把它倒过来了。不使用ref
g时,g的值将为f
(在您的示例中为0x2A53BC
)复制到名为g
的新变量中g
和f
彼此完全独立,但它们都持有“值”0x2A53BC
。当您执行g=null时
变量f
仍将保持0x2A53BC
,但g现在将保持0x000000
注意:我不确定下一部分的内容,我可能会告诉您事实上不正确的信息,但我是在描述外部观察者的正确行为。
使用ref
时,变量g
将指向f
值的地址(比如0x154AFA
),而f
仍然指向0x2A53BC
。当您执行g=null时
g的值不会更新,它仍然指向0x154AFA
,但是f
现在将指向0x000000
,因此Foo
是类
类型,尤其是引用类型。你有:
var f = new Foo();
因此f
的值实际上是对实际对象的引用。正如您所说,我们可能认为引用是一个整数,比如说0x2A53BC
(为了具体起见,我们实际上无法访问整数或任何引用;这些引用没有指针算法)
现在,当您通过值传递时,与重载一样:
void Test(Foo g) { g = null; }
void Test(ref Foo g) { g = null; }
我们称之为Test(f)
,值0x2A53BC
将复制到一个新的存储位置(堆栈上的新位置),该新存储位置将变为g
。如果您使用了g
来变异现有实例,那么由于两个存储位置都保存相同的信息0x2A53BC
,因此您也会变异f
指向的实例。但是您可以选择分配给g
。这导致了g
的新存储位置出现了一个错误,现在保存着引用0x000000
(我们简单地假设零被用作null
的表示)。它显然不会更改f
的存储位置,它仍然指向位于0x2A53BC
的原始实例
相反,对于其他过载:
void Test(Foo g) { g = null; }
void Test(ref Foo g) { g = null; }
我们称之为Test(参考f)代码>,我们通过引用传递。因此,对g
使用的存储位置与对f
使用的存储位置相同。未复制值0x2A53BC
。当您分配g=null时
,即原始的0x2A53BC
被0x000000
(null
的神奇表示法)覆盖。当方法返回时,即使在返回之前,f
已将其值更改为指向新的“位置”0x000000
总而言之:引用类型的“值”就是引用。按值传递时,将生成引用“number”的副本,并由调用的方法使用。通过引用传递时,不会复制值,被调用方方法和调用方方法使用相同的存储位置
补充:C#规范中的一些引用:
5.1.4数值参数
未使用ref
或out
修饰符声明的参数是
值参数
一个值参数出现了
调用函数成员(方法、实例构造函数、,
访问器(或运算符)或匿名函数
属于,并使用中给定的参数值初始化
调用。返回时,值参数通常不再存在
函数成员或匿名函数的名称。[……]
5.1.5参考参数
使用ref
修饰符声明的参数是参考参数
A
引用参数不会创建新的存储位置。取而代之的是
reference参数表示的存储位置与
在函数成员或匿名中作为参数给定的变量
函数调用。因此,参考参数的值是
始终与基础变量相同。[……]
旧相关thr