I'm currently experiencing an issue when using an auto-generated property for a class member. Calling a method on the class should update the property, but it doesn't seem to work.
I'm updating some old C# code and VS2017 advises me few refactoring tips, for instance, private members with manually provided properties to auto-generated properties.
VS makes this easy with a couple of clicks, and everything compiles just fine. The problem is that code does not work as before.
Consider the following reduced code example:
using System;
public class Program
{
struct A
{
public A(int x) : this()
{
X = x;
}
public int X { get; private set; }
public void Update(int y)
{
X += y;
}
}
class B
{
private A _secondVar;
public B()
{
}
public A MyVar { get; set; }
public A SecondVar
{
get { return _secondVar; }
protected set { _secondVar = value; }
}
public void Foo(int z)
{
MyVar.Update(z);
_secondVar.Update(z);
}
}
public static void Main()
{
B b = new B();
Console.WriteLine("BEFORE: b.MyVar: " + b.MyVar.X + ", b.SecondVar: " + b.SecondVar.X );
b.Foo(23);
Console.WriteLine("AFTER: b.MyVar: " + b.MyVar.X + ", b.SecondVar: " + b.SecondVar.X );
}
}
The output is:
BEFORE: b.MyVar: 0, b.SecondVar: 0
AFTER: b.MyVar: 0, b.SecondVar: 23
I would expect that calling MyVar.Update(z)
would update the property, and subsequent calls to MyVar.X
should provide the updated value.
Is this expected behavior, or a bug in C#?
You're using mutable structs, which is strongly discouraged for precisely this reason.
Your code here:
public void Foo(int z)
{
MyVar.Update(z);
_secondVar.Update(z);
}
is equivalent to this:
public void Foo(int z)
{
A tmp = MyVar; // Creates a copy
tmp.Update(z);
_secondVar.Update(z);
}
Your _secondVar.Update(z)
code changes the value of _secondVar
because you're calling it directly on a variable. That's not the case with your property - using a property getter is effectively calling a method that returns a value, which is a copy of the variable value.
If you were to use classes, you'd see the behaviour you expect, because then you wouldn't be trying to change the value of the underlying variable, but change the content within the object it refers to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With