我有以下代码:
static void Main(string[] args)
{
myclass c = new myclass();
c.test1 = 1;
myclass c2 = TestPassByValByRef(c);
Console.WriteLine("c.Test1: {0}", c.test1);
Console.WriteLine("c2.Test1: {0}", c2.test1);
Console.ReadLine();
}
private static myclass TestPassByValByRef(myclass c)
{
Console.WriteLine("Before NowPassByRef c.Test1: {0}", c.test1);
NowPassByRef(ref c);
Console.WriteLine("After NowPassByRef c.Test1: {0}", c.test1);
return c;
}
private static void NowPassByRef(ref myclass c)
{
c = new myclass();
c.test1 = 10;
c.test2 = 25;
}
输出是c2保留更改的值,而c不保留。
我的问题是:c
中的TestPassByValByRef
会发生什么?
答案 0 :(得分:2)
当您致电TestPassByValByRef
时,您的对象有两个引用 - Main
中的引用,以及TestPassByValByRef
参数的引用。这是因为在C#'中按值传递引用类型(不是struct
的任何内容)实际上是按值传递引用,而不是对象本身。因此,复制了引用,现在有两个对原始对象的引用。
调用NowPassByRef
后,TestPassByValByRef
的参考副本已被myclass
的新实例的引用覆盖,但由于Main
中仍有引用1}}该对象不符合垃圾回收的条件。
因此,对“发生的事情”的简短回答是“没有”。
答案 1 :(得分:0)
在第一种情况下,您将{strong>按值 a reference
传递给您的对象。
因此,当您在第一种情况下执行 时,您需要new
,重新初始化reference
的副本,因此它将失去与原始物体。
在第二种情况下,您传递reference
本身,因此使用new
重新初始化它也会更改它指向的内存位置。
答案 2 :(得分:0)
在您的以下代码中,您c = new myclass();
为object c
创建一个新的内存引用,该引用不指向已通过的内存。因此,您无法将更改反映到您创建的第一个对象。
private static void NowPassByRef(ref myclass c)
{
c = new myclass(); // it will create new memory reference
c.test1 = 10;
c.test2 = 25;
}
因此它将显示c不会被更改并输出为:
Before NowPassByRef c.Test1: 1
After NowPassByRef c.Test1: 10
c.Test1: 1
c2.Test1: 10
暂时只评论方法中的c = new myclass();
,它会反映object c
的更改。它将清除你对引用指针等的怀疑。
private static void NowPassByRef(ref myclass c)
{
//c = new myclass(); // it will create new memory reference
c.test1 = 10;
c.test2 = 25;
}
现在输出将是:
Before NowPassByRef c.Test1: 1
After NowPassByRef c.Test1: 10
c.Test1: 10
c2.Test1: 10
我认为 - C# pass by value/ref? 必须是您解释的问题信息并检查John Skeet关于Parameter passing in C#的文章。
答案 3 :(得分:0)
static void Main(string[] args)
{
myclass c = new myclass();
c.test1 = 1;
myclass c2 = TestPassByValByRef(c);
Console.WriteLine("c.Test1: {0}", c.test1);
Console.WriteLine("c2.Test1: {0}", c2.test1);
Console.ReadLine();
}
main
包含两个引用,这两个引用都可以引用myclass
类型的对象。在c
之前初始化TestPassByValByRef
,c2
由该方法的返回值初始化。
private static myclass TestPassByValByRef(myclass c)
{
Console.WriteLine("Before NowPassByRef c.Test1: {0}", c.test1);
NowPassByRef(ref c);
Console.WriteLine("After NowPassByRef c.Test1: {0}", c.test1);
return c;
}
TestPassByValByRef
包含一个名为c
的引用。它最初包含作为参数传递给它的引用的副本(因为该参数是按值传递的)。 然后通过引用NowPassByRef
传递此引用并返回。
private static void NowPassByRef(ref myclass c)
{
c = new myclass();
c.test1 = 10;
c.test2 = 25;
}
NowPassByRef
与其调用方法共享引用c
。它会在返回之前立即将其重新分配给新值。
您期望发生什么?