这可以应用于许多不同的语言,但我特别使用C#和INotifyPropertyChanged。
如果设置了属性,即使它没有改变,我应该重新分配它的值吗? 例如:
public int IntProperty
...
set
{
var oldValue = _intProperty;
_intProperty = value;
if (!Equals(value, oldValue))
{
OnPropertyChanged(...);
}
}
VS
public int IntProperty
...
set
{
if (!Equals(value, _intProperty))
{
_intProperty = value;
OnPropertyChanged(...);
}
}
我无法决定。从技术上讲,它不应该有所作为,但有一些奇怪的极端情况(如不应该发生的奇怪的Equals实现)可能会改变行为。
答案 0 :(得分:2)
这可能受到财产类型的影响。有些类有智能Equals方法,有些则没有。如果你信任你,那应该没关系,但是如果这个类没有覆盖Equals,或者没有做得好,那么它会改变一些事情。总的来说,我会说没有发送通知就不会改变基础值,所以我选择#2。
举一个例子,也许有一个简单的数据持有者看起来像这样:
class Data
{
public int ID { get; set; }
public string SomeData { get; set; }
public string SomeOtherData { get; set; }
//Assume there are lots of other fields here
public override bool Equals(object obj)
{
Data other = obj as Data;
if (other != null)
{
return ID == other.ID;
}
return false;
}
}
现在,如果ID 假设是唯一的(可能因为它映射到数据库ID值),那么这不是一个想法,但它不会阻止人们四处走动创建具有相同ID和不同数据值的对象。如果某些卑鄙的人这样做,你最终可能会为某个属性设置一个值,例如你的新值确实显着不同,但是.Equals会说它们是相同的。现在无论发生什么事,你都有点搞砸了,但更糟糕的是,没有设置一个不应该不同的值,而是(因为集合在if中)或者更改了值而没有通知事件订阅者该事件改变了吗? (您还有第三个选项来设置事件并通知人们即使它发生了变化,也可能表明这是通过事件args的情况。)如果事件订阅者是持续更改数据库的代码(通常是这种类型的结构的情况)那么你正在改变一个内存中的值,认为它确实改变了(让它退出是一个精确的参考匹配),但该值仍然不会被持久化,因为事件没有被触发
对不起文字墙。
tl; dr版本,无论你做什么,这段代码的用户都可以找到一种方法来搞砸你;最终,您需要对它们的最小信任才能使您的代码生效。
答案 1 :(得分:1)
再次设置它是没有用的,只需要时间/节省性能。
由于通知已经在if语句中,因此它也不再是代码。
答案 2 :(得分:1)
如果您打算以任何一种方式进行检查,那么我会说如果它们相等则不要担心设置值。节省自己的周期。
答案 3 :(得分:1)
简短回答 - 一般来说,要么检查它们是否不同,只有在它是,或者不打扰检查时才设置它。
更长的答案 - 对于MVVM,一种被接受的做法是将集合抽象为基类,其中有两个函数重载来设置属性。这应该处理所有设置属性的情况,使它们更容易在继承的类中实现,并清理它们。
public event PropertyChangedEventHandler PropertyChanged;
public Boolean SetProperty<T>(string propertyName, ref T field, T value, IEqualityComparer<T> comparer)
{
if (!comparer.Equals(field, value))
{
T oldValue = field;
field = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
public Boolean SetProperty<T>(string propertyName, ref T field, T value)
{
return SetProperty(propertyName, ref field, value, EqualityComparer<T>.Default);
}
然后,在您的ViewModel中,您将执行以下操作:
private int mMyIntProperty = 0;
public string MyIntProperty
{
get { return mMyIntProperty; }
set { SetProperty("MyIntProperty", ref mMyIntProperty, value); }
}
对于简单类型,您不需要指定Comparer,因为默认情况下会很好。但是,使用比较器可以更轻松地检查复杂类型。