引用类型vs值类型

本文关键字:类型 vs 引用类型 | 更新日期: 2023-09-27 18:07:20

我正在阅读c#中的结构体和类,我的理解是结构体是值类型,类是引用类型。但是我对类对象作为参数传递给方法时的行为有点困惑。

假设我有以下代码:

public class Program
{
    public static void Main(string[] args)
    {
        var program = new Program();
        var person = new Person
        {
            Firstname = "Bob",
        };
        Console.WriteLine(person.Firstname);
        program.ChangeName(person);
        Console.WriteLine(person.Firstname);
        program.Kill(person);
        Console.WriteLine(person.Firstname);
        Console.Read();
    }
    public void ChangeName(Person p)
    {
        p.Firstname = "Alice";
    }
    public void Kill(Person p)
    {
        p = null;
    }
}

当我将Person类的实例传递给Program.ChangeName()并将person.Firstname的值更改为Alice时,更改反映在我的Program.Main()中实例化的原始人员对象上,这是我所期望的,p参数是对person的引用。但是,当我尝试将p设置为null时,似乎没有变化。为什么会这样?

引用类型vs值类型

当您"通过引用传递"时,您实际上是在传递引用的副本,因此将该引用设置为指向另一个对象(或null)不会影响原始引用。但是,如果您通过解引用指针副本来更改对象的属性,则调用者将看到这些更改。

如果你想真正通过引用传递并使你的kill方法工作,你可以添加ref关键字:

public void Kill(ref Person p)
{
    p = null;
}

您正在将引用的副本设置为null,这不会影响原始值。

类似于(c++中的)

Person * myPtr = new Person();
NullFunc(myPtr);
public NullFunc(Person * ptr)
{
   ptr = null;
}

引用是有效的值传递,你不能改变它。但是,您可以更改它所指向的对象的属性:

ptr->Name = "Bob";

明显影响原对象