我在一个类中有两个互相更新的属性:binary
和value
,其中binary
是二进制值,而value
是基数10。彼此更新,以便在调用set
的{{1}}方法时,value
被更新,反之亦然。
binary
如果当前的private UInt64 _Binary;
public UInt64 Binary {
get { return _Binary; }
set
{
if (_Binary != value) {
_Binary = value;
BinaryToValue();
UpdateUi();
}
}
}
private double _Value;
public double Value {
get { return _Value; }
set
{
if (_Value != value) {
_Value = value;
ValueToBinary();
}
}
}
private void ValueToBinary() {
// Loop through and set each bit high or low as needed
}
是十进制的Value
,而1
的LSB仅被设置为高,那么如果我将值更改为Binary
,现在我将进行设置3位不同的值,这意味着6
的{{1}}方法每次都看到不同的值(将位0设置为低(值= 0),将位1设置为高(值= 2),将位设置为1 2高(值= 4)。在这种情况下,set
也被调用了三次,因此,当三个位中的每一个都设置为不同的状态时,Binary
属性将发生变化,这不应该是因为{{1} }属性最初包含正确的值。
如何防止这种情况发生?
我无法更新后备字段,因为修改BinaryToValue()
时需要更新UI。我看了一个问题:Properties that update each other,但是那里的解决方案在这里不适用,因为我不能仅更新后备字段。
答案 0 :(得分:3)
正确的方法是只序列化一个序列,而另一个序列只是一个将其转换称为调用程序的吸气剂(如果考虑到性能,可以存储脏标志并使用缓存的值)。但是,如果它们以不同的方式表示相同的事物,那么两者可能应该不可设置。您可以提供以两种方式进行设置的方法,但只能使用一个字段来存储值。
如果您坚持要这样做,只需在更新后备字段后调用UI更新即可。属性不能互相更新,因为这会导致循环
答案 1 :(得分:0)
正如米尔尼所说(如果您真的想这样做),请对两个属性仅使用一个后备字段:
private UInt64 binary;
public UInt64 Binary { get { return binary; } set { binary = value; UpdateUi(); } }
public double Value { get { return BinaryToValue(); } set { ValueToBinary(value); } }
private double BinaryToValue()
{
double binaryToValue = 0;
// logic (convert binary field to double and set it to binaryToValue)
return binaryToValue;
}
private double lastValue;
private void ValueToBinary(double value)
{
if (value != lastValue)
{
lastValue = value;
// logic (Binary (the property to activate UpdateUi()) = ...)
}
}
您还可以删除Value
的设置方法,并按照Milney的建议将其设置为public
的方法。
注意:属性的唯一工作应该是获取和/或设置背景字段的值(验证其输入并在INotifyPropertyChanged
interface is implemented时通知更改),而不更改其他属性值(产生副作用),加强了米尔尼对塞特方法的推荐。