这个问题在这里已有答案:
考虑以下情况:
public class Test
{
public Test()
{
text = "By default";
}
public string text { get; set; }
public void GiveMeClass(Test t)
{
t.text = "I have a class";
}
public void GiveMeRef(ref Test t)
{
t.text = "I have a ref";
}
}
调用代码:
Test t = new Test();
Console.WriteLine(t.text);
t.GiveMeClass(t);
Console.WriteLine(t.text);
t.GiveMeRef(ref t);
Console.WriteLine(t.text);
这将写下以下文字:
By default
I have a class
I have a ref
现在,如果我们通过分配测试类的新实例来改变方法中的代码,就像在下面的代码中一样:
public class Test
{
public Test()
{
text = "By default";
}
public string text { get; set; }
public void GiveMeClass(Test t)
{
t = new Test() { text = "I have a class" };
}
public void GiveMeRef(ref Test t)
{
t = new Test() { text = "I have a ref" };
}
}
调用代码将写下以下文本:
By default
By default
I have a ref
正如您所看到的,当调用GiveMeClass方法时,Test类的实例没有改变(因为输出文本是“默认情况下”,而不是“我有一个类”)。所以问题是,如果通过引用方法传递类,为什么赋值t = new Test() { text = "I have a class" };
不会在调用者代码中更改Test类的原始实例?
类始终通过引用传递,但更改:
t = new Test() { text = "I have a class" }; // this is t2 (new class instance is created and assigned into t valid only for this method)
不会被反映出来,因为调用方法的地方是:
Test t = new Test(); // this is t1
t.GiveMeClass(t); // this is t1 on input and will not change
Console.WriteLine(t.text); // this is still t1
不会更改第一个赋值,只重写函数GiveMeClass
中的赋值
这里的The answer正是您正在寻找的。请阅读。总之,C#中参数的默认约定是按值传递。无论参数是类还是结构,都是如此。在类的情况下,仅通过值传递引用,而在结构情况下,传递整个对象的浅表副本。这将创建一个新对象并为其指向Test类。
在下面的方法中,t是对原始对象的引用,它是通过值而不是通过引用传递的。
public void GiveMeRef(Test t -> a copy of t that points to original object address)
{
t = new Test() { text = "I have a class" }; -> the copy of t is now pointing to a new object
}
因此,当您显示结果时,原始t变量仍指向对象测试(默认情况下具有文本“)
t.GiveMeRef(ref t);
Console.WriteLine(t.text);