C# Properties as Reference
Solution 1
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.
Solution 2
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, string
s 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.
freewill
Updated on June 04, 2022Comments
-
freewill almost 2 years
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;
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 :)
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?
-
Brian over 10 yearsVery well-explained Michael, +1.
-
freewill over 10 yearsThank you. That's the exact description that address my problem and clears my doubts. However other friends pushes me hard not to use ref keyword :)
-
freewill over 10 yearsThanks Tim. I will follow your suggestions about ref/out and fundemantals. I have lots of methods running in an order; all have "ref ErrorStatus err" reference in method arguments; all these methods add their error status to this variable(like a logger). I will check if this can be done better upon your suggestions.
-
Michael Edenfield over 10 yearsThere is nothing wrong with using ref parameters when they are needed, but you should make sure you really need them. Often times the desire to have ref parameters indicates a flaw in your design that could be solved in a better way,
-
freewill over 10 yearsThanks Michael I've studied deeper it. A cleaner, readable, better solution offered is to return a "Result" class instead of using ref or out variables. I was using always bool as "return" and ref/out for status code and error messages in methods. I thnik it comes from old habbits and old style programming. Now result class style looks really better. You have been very helpful. Thank you very much.