通过ref和没有将类对象传递给方法之间的区别(考虑了几种情况)[重复]

问题描述 投票:1回答:3

考虑以下情况:

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

c# class methods reference pass-by-reference
3个回答
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
投票

这里的The answer正是您正在寻找的。请阅读。总之,C#中参数的默认约定是按值传递。无论参数是类还是结构,都是如此。在类的情况下,仅通过值传递引用,而在结构情况下,传递整个对象的浅表副本。这将创建一个新对象并为其指向Test类。


0
投票

在下面的方法中,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);
© www.soinside.com 2019 - 2024. All rights reserved.