使用ref和不使用ref将类对象传递给方法之间的区别(考虑了几种情况)

时间:2018-09-05 06:04:57

标签: c# class methods reference pass-by-reference

请考虑以下情况:

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类的原始实例?

3 个答案:

答案 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 
}