在C#中传递引用类型

class Test { static void Func(StringBuilder myString) { myString.Append ("test"); myString = null; } static void Main() { StringBuilder s1 = new StringBuilder(); Func(s1); Console.WriteLine (s1); } } 

输出是“测试”,为什么不是空?

如果通过引用 Func()传递s1,那么为什么myString.Append("test")改变它,但是myString = null却没有?

提前致谢。

如果通过引用Func()传递s1,那么myString.Append(“test”)为什么会改变它

它不是通过引用传递的,而是将其地址值传递给函数。

假设S1指向内存位置0x48,这将传递给Func ,其中Func参数myString将开始指向该位置。 稍后当您Append文本Append到该位置时,会添加该文本。 但是稍后当你为myString分配null时,它开始指向什么,但原始位置保持不变。

您应该看到: Jon Skeet在C#中传递参数

请考虑以下图表。 在第1步中,您将创建一个StringBuilder类型的新对象,并让S1引用该对象。

在此处输入图像描述

在步骤2中,在将S1传递给Func ,现在myString也指向内存中的同一对象。

在此处输入图像描述

稍后当你Append ,通过myString短信时,它会更新原始对象,因为myString指向对象持有的内存位置。

在步骤3中,当您为myString分配null时,它会丢失StringBuilder对象的地址,但这不会更改对象或指针S1中的任何内容。

在此处输入图像描述

您是按值传递对象的引用。

即对象的地址按值传递,但对象和对象的地址是相同的。 因此,当您调用方法时,VM会复制引用; 你只是在改变副本。

myString.Append您使用复制的引用来获取对象(仍然只有一个对象),然后更改/调用该对象。

你认为你在做什么是这样的:

 class Test { static void Func(ref StringBuilder myString) { myString.Append("test"); myString = null; } static void Main(string[] args) { StringBuilder s1 = new StringBuilder(); Func(ref s1); Console.WriteLine(s1); } } 

更长的解释: http : //javadude.com/articles/passbyvalue.htm

在C#中,默认情况下,复数类型的指针(引用)按值传递。 您必须指定它是通过引用传递的,如下所示:

 static void Func(ref StringBuilder myString) { myString.Append ("test"); myString = null; } 

ref添加到函数以通过ref传递它。

 static void Func(ref StringBuilder myString) { myString.Append ("test"); myString = null; } 

然后称之为:

 Func(ref s1); 

因为您将StringBuilder s1的引用传递给Func。 在Func中,对同一个StringBuilder实例的引用称为“myString”。 首先告诉它做某事(“ myString.Append("Test") ),然后将引用INSIDE Func设置为null。Append的结果对Main()可见;引用设置为null不会影响s1 in主要。