Reference type vs value type [duplicate]

2019-01-27 05:50发布

This question already has an answer here:

I'm reading about structs and classes in C# and to my understanding structs are value types and classes are reference types. But I'm a little confused about how class objects behave when they are passed as parameters to a method.

Assume I have the following code:

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;
    }
}

When I pass my instance of the Person class to Program.ChangeName() and change the value of person.Firstname to Alice, the change is reflected on the original person object as instantiated in my Program.Main() which is what I would expect, the p parameter is a reference to person. However, when I attempt to set p to null, there appears to be no change. Why is this?

2条回答
来,给爷笑一个
2楼-- · 2019-01-27 06:00

You are setting your copy of the reference to null, which doesn't affect the original value.

It is analogous to (in C++)

Person * myPtr = new Person();
NullFunc(myPtr);

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

The reference is effectively passed by value, you can't change it. You can change properties on the object that it points to however:

ptr->Name = "Bob";

Clearly affects the original object.

查看更多
何必那么认真
3楼-- · 2019-01-27 06:17

When you "pass by reference" you are really passing a copy of the reference, so setting that reference to point to another object (or null) won't affect the original reference. However if you change properties on the object by dereferencing your copy of the pointer, those changes will be seen by the caller.

If you wanted to truly pass by reference and cause your kill method to work, you could add the ref keyword:

public void Kill(ref Person p)
{
    p = null;
}
查看更多
登录 后发表回答