Frage

Basic fundamental I messed up with C# Properties and reference types.

public Address adr { get; set; }

public class Address
{

    //Field
    public string AddressLine1;   

    //Property
    public string Country {get; set;}
}

public void ChangeCountry(string _Country)
{
    _Country = "US";
}

public void ChangeAddress(Address _adr)
{
    _adr.Country = "US";
}

private void button1_Click(object sender, EventArgs e)
{
    adr = new Address();
    ChangeCountry(adr.Country);

    MessageBox.Show(adr.Country);
    //(?)Country is reported empty string. Property did not updated outside.

    ChangeAddress(adr);

    MessageBox.Show(adr.Country);
    //OK. Country is reported 'US'


}

Here my questions;

  1. When we pass a Property(simple or complex one) directly to a method that will attempt to modify it, Is it ensured this property modified everywhere? I mean Like the ref keyword? Since I can't use the "ref" keyword with properties;I directly pass property to a method for modification and I'm not sure if it is always going to be updated/modified also at outside. When I dont see ref keyword; it makes me worried :)

  2. In the above example; adr class is updated successfully(ChangeAddress) without ref keyword; but the ChangeCountry method could not updated the string Country property. Is this a special case for strings?

War es hilfreich?

Lösung

No, properties that are passed into methods are not modified in that method, because you cannot pass them by reference. Properties are always passed by value, so you cannot change their value within the methods that you pass them two.

However, that's not actually what you are doing in both methods, and that's why one works and one does not.

Your first method:

public void ChangeCountry(string _Country)
{
    _Country = "US";
}

attempts to change the value of the parameter that does not have the ref keyword, which fails (as you noted).

Your second method,

public void ChangeAddress(Address _adr)
{
    _adr.Country = "US";
}

is not trying to change the value of its parameter. The Address object that you pass into the method remains the same instance of Address for the entire method. However, because Address is a reference type, you can change its properties, and those changes will persist once the method returns. They will also be visible to any other places that have a reference to the same instance.

To see the difference, if you had tried to do this in your second method, it would have failed, for the same reason your first method does:

public void ChangeAddress(Address _adr)
{
    _adr = new Address();
    _adr.Country = "US";
}

Here, you are trying to change the value of the parameter -- to a new instance of the class -- and that doesn't work without the ref keyword.

Andere Tipps

When I see the ref keyword, it makes me worried. In the vast majority of cases, there is a better solution. ref and out should be used sparingly. I can see two fairly good ways to solve your problem, from what I can see in your example:

string GetNewCountry() { return "US"; } // pass in existing Address if needed

adr.Country = GetNewCountry();

// or

public void ChangeAddress(Address adr)
{
    adr.Country = "US";
}

To answer your second question, strings aren't particularly special, they are just another immutable type. If you study up on how references are passed and modified in C#, the behavior you see will be perfectly clear: in the one case, you are modifying the mutable Address object, and in the other, you are replacing the local variable with a reference to a different string object.

This has less to do with pass by reference than you might think.

You have method ChangeCountry(Address a) that accepts an object of type Address

Instead of passing it an Address object you are passing it the String property (Country) of the address object when you call ChangeCountry(adr.Country).

To make your code modify the Address object you need to call the ChangeCountry(adr).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top