FPGA
FPGA

Reputation: 3855

Initializing an object with a property that is dependent on another property

Consider this class

class SomeObject
{
        private int x;
        public int X
        {
            get { return x; }
            set { x = value+z; }
        }

        private int y;
        public int Y
        {
            get { return y; }
            set { y = value+z ; }
        }

        private int z;
        public int Z
        {
            get {return z;}
            set { z = value+y ; }
        }
    }

When I do something like

var r = new SomeObject() {X = 1, Y = 1, Z = 1 };
Console.WriteLine(r.X + " " + r.Y + " " + r.Z);

var r1 = new SomeObject() { Y = 1, X = 1, Z = 1 };
Console.WriteLine(r1.X + " " + r1.Y + " " + r1.Z);

var r2 = new SomeObject() { Z = 1, X = 1, Y = 1 };
Console.WriteLine(r2.X + " " + r2.Y + " " + r2.Z);

The console outputs

1 1 2
1 1 2
2 2 1

Is there a way to fix this behaviour other than using the constructor?

The right output shall be 2 2 2

every answer was helpful but i can't marke them all as best answer

Upvotes: 1

Views: 996

Answers (3)

hawk
hawk

Reputation: 1847

Instead of storing the value with the dependent variable, you could always compute it only in the getter. This way the order they get set wouldn't matter. For example

    private int y;
    public int Y
    {
        get { return y +z; }
        set { y = value ; }
    }

and similar for the other properties.

However I must add that what you're trying to achieve through properties is counter-intuitive and can be problem for any other programmer coming across this.

Upvotes: 4

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

There is no problem. Perfectly correct behavior. When you're setting Z first it will work as you expect. Otherwise Z is 0 while you're setting other properties and value + Z == value.
Just use constructor:

public SomeObject(int x, int y, int z)
{
   this.x = x + z;
   this.y = y + z;
   this.z = z + y;
}

You can always use named parameters:

var r = new SomeObject(x: 1, z: 1, y: 1);

Upvotes: 2

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

This is terrible, don't modify value in set accessor.

If I set value Y = 10 I'd like to see that 10 back.

I would do something like this with readonly properties

public int XModified
{
    get { return x + z; }
}

and so on.

Upvotes: 2

Related Questions