How can I protect myself from updating another object by the current object by mistake?

Can you suggest me a way that would interfere with me when I work with reference types?

var someCost = new Cost( Price: new Price(1000, "USD") , CostType: "Type-A") ; var candyCost = new Cost(); // Initialize candyCost.Price candyCost.Price = someCost.Price; //Now candyCost Price is referencing // price of someCost; // (.......) // Some logic and code here //and I forgot that I was referencing to someCost object price object //and I do stupid mistake: candyCost.Price.Value = 5000; //Now I believe I have updated candyCost price //but I have also updated someCost!! 

The rest of the story is about debugging to find out why someCost Price is being updated.

I wanted to simplify the problem with this example. Hope if you get my point.

Question Can you recommend me a way to protect myself from repeating such a mistake? any design patterns when it comes to updating values ​​related to reference types.

+4
source share
9 answers

Your Price object must be immutable - this will force you to assign a new Price object instead of changing the price of an existing one, therefore avoiding the side effect.

+8
source

Depends on what you want to achieve with this line:

  candyCost.Price = someCost.Price; 

You want to say that candyCost and someCost have the same price at this moment or that they always have the same price?

If you just want to initialize candyCost.Price with a value equal to someCost.Prize than you should clone an instance of Price :

  candyCost.Price = new Price(someCost.Price); // copy constructor pattern inside 

(of course you must implement the constructor)

+2
source

Two local variables that represent the same thing are never created in.

+1
source

Create a deep copy of the Price class by implementing the IClonnable interface. Then, when you set a price, you will say

 a.Price = b.Price.Clone(); // will return a new object of the price after assigning the internal value types 

or

  Class Cost{ private Price _price; public Price PriceValue { get { _price.Clone(); } set { _price = value; } } } 

that way you will never forget

therefore, you cannot access the _price field directly, unless you name the Getter property, which ultimately returns a deep copy of the price

+1
source

In this case, I would suggest using struct (value-type) instead of class (reference type). Thus, it is impossible to refer to the same instance, since there is no link there, the value itself is saved :)

You can also use properties of type Price read-only and specify only a constructor. Thus, you can refer to another copy, but this is not a problem - they will remain with the same value, because to set a new value you will need to create a new object.

0
source

You want value-based behavior for the Price property. The getter must return a copy of the Price object.

0
source

There are several ways to do this.

  • Use immutable types - for example. String in Java and all primitive wrappers
  • Use copy constructors to copy objects instead of referencing them

Invariance may seem like a rather painfully restrictive method at first, but it is actually quite common and provides what you are trying to do well enough.

Using copy constructors means you have to make sure that whenever you return an object (e.g. from a getter), you actually create a new object, similarly whenever you use a transferred object (e.g. a setter), you need to copy it .

0
source

Make Cost.Price read-only using {get; private set;} Add a new method to the price, called SetPrice, which takes the price and creates a new instance of the price

 SetPrice(Price price) { this.Price = price.Clone(); } 

You will need to do an implementation of Price IClonnable

0
source

Depending on the language, you can overload the operator. So, overload the assignment operator ( = ) and execute a deep clone in the overloaded operator body.

0
source

Source: https://habr.com/ru/post/1346917/


All Articles