请考虑以下情况:
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
现在,如果我们通过分配 t Test类的新实例来更改方法中的代码,如以下代码所示:
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类的原始实例?
答案 0 :(得分:1)
类总是通过引用传递,但更改为:
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
答案 1 :(得分:1)
The answer正是您想要的。请阅读。总之,C#中参数的默认约定是按值传递。无论参数是class还是struct,都是这样。在类情况下,只是按值传递引用,而在结构情况下,则传递整个对象的浅表副本。这将创建一个新对象,并将Test类指向它。
答案 2 :(得分:0)
在下面的方法中,t是对原始对象的引用,它是通过值而不是通过引用传递的。
<C-H>
因此,当您显示结果时,原始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
}