如何确保自己不会错误地更新当前对象上的另一个对象?

发布于 2024-10-30 05:04:23 字数 802 浏览 1 评论 0原文

您能否建议我一种方法,在我使用引用类型时防止出现这种情况?

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's 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!!

故事的其余部分是关于调试以找出为什么 someCost 的价格会更新。

我想用这个例子来简化问题。我希望你能明白我的意思。

问题:您能给我推荐一种方法来确保自己不再犯这样的错误吗?涉及更新引用类型上的值时的任何设计模式。

Can you suggest me a way that would prevent me from such a case when I am working 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's 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!!

Rest of the story is about debugging to find out why someCost's Price is updated.

I wanted to simplify the problem with this example. I hope if you get my meaning.

Question: Can you recommend me a way to secure myself from repeating such a mistake? any design patterns when it comes to updating values that are on reference types.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

木有鱼丸 2024-11-06 05:04:23

您的 Price 对象应该是不可变的 - 这将迫使您分配一个新的 Price 对象,而不是更改现有对象的价格,从而避免副作用。

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

白日梦 2024-11-06 05:04:23

取决于您想通过这一行实现什么:

 candyCost.Price = someCost.Price;

您是否想说 candyCostsomeCost 此时 具有相同的价格,或者他们总是有相同的价格?

如果您只想使用等于 someCost.Prize 的值来初始化 candyCost.Price,那么您应该克隆 Price实例:(

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

当然你必须实现构造函数)

Depends on what you want to achieve with this line:

 candyCost.Price = someCost.Price;

Do 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 that is equal to someCost.Prize, than you should clone the Price instance:

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

(of course you have to implement the constructor)

天冷不及心凉 2024-11-06 05:04:23

从不创建两个表示相同事物的局部变量。

By never creating two local variables that represent the same thing.

樱花坊 2024-11-06 05:04:23

通过实现 IClonnable 接口创建 Price 类的深层副本。然后,当您分配价格时,您会说

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

或者

  Class Cost{
  private Price _price;

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

这样您将永远不会忘记

,因此您无法直接访问 _price 字段,除非您调用 Getter 属性,该属性最终将返回价格的深层副本

Create a deep copy of the class Price by implementing the IClonnable interface. Then when you assign the price you would 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; }
        }
       }

this way you will never forget

hence you cannot access _price field directly, unless you call the Getter property which will eventually return a deep copy of the Price

似梦非梦 2024-11-06 05:04:23

在这种情况下,我建议使用struct(值类型)而不是class(引用类型)。这样就不可能引用同一个实例,因为没有“引用”,值本身被存储:)

您还可以将 Price 类型的属性设置为只读,并且仅设置由构造函数。这样您就可以引用另一个副本,但这没有问题 - 它们都将保持相同的值,因为要设置为新值,您需要创建一个新对象。

In this case I'd suggest using a struct (value-type) instead of a class (reference type). That way it's not possible to refer to the same instance, because there's no 'reference', the value itself is stored :)

You could also have the properties of the Price type read-only, and set only by the constructor. That way you can reference another copy, but that's no problem - they'll both stay at the same value because to set to a new value you'd need to create a new object.

对风讲故事 2024-11-06 05:04:23

您希望 Price 属性具有按值行为。 getter 应该返回 Price 对象的副本。

You want a by-value behaviour for the Price property. The getter should return a copy of the Price object.

风渺 2024-11-06 05:04:23

有几种方法可以做到这一点。

  1. 使用不可变类型 - 例如 Java 中的 String 和所有原始包装器
  2. 使用复制构造函数来复制对象而不是引用它们

不可变性乍一看似乎是一种非常痛苦的限制性方法,但实际上它很常见,并且很好地强制执行了您想要做的事情。

使用复制构造函数意味着您必须确保每当您返回一个对象(例如,从 getter)时,您实际上都会创建一个新对象,同样,每当您使用传入的对象(例如,setter)时,您都需要复制它。

There are a couple of ways of doing it.

  1. Use immutable types - e.g. String in Java, and all the primitive wrappers
  2. Use copy constructors to copy objects instead of referencing them

Immutability might seem like quite a painfully restrictive method at first but actually it's quite common and enforces what you are trying to do quite well.

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 passed in object (e.g. setter) you need to copy it.

娇俏 2024-11-06 05:04:23

使用 {get; 将 Cost.Price 设为只读私人套装;}
向 Cost 添加一个名为 SetPrice 的新方法,该方法接受 Price 并创建一个新的 Price 实例

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

您需要使 Price 实现 IClonnable

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

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

You will need to make Price implement IClonnable

二智少女 2024-11-06 05:04:23

根据语言的不同,您可以进行运算符重载。因此,重载赋值运算符 (=) 并在重载的运算符主体中执行深度克隆。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文