为什么ObservableCollection< T>实现INotifyPropertyChanged? [英] Why does ObservableCollection<T> implement INotifyPropertyChanged?
问题描述
在.NET 4.0中,没有ObservableCollection<T>
定义的单个属性,也没有覆盖其父级或接口的任何属性.那么为什么ObservableCollection<T>
实现INotifyPropertyChanged
?
In .NET 4.0, there isn't a single property defined by ObservableCollection<T>
nor does it override any property of its parent or interfaces. So why does ObservableCollection<T>
implement INotifyPropertyChanged
?
我能想到的一个原因是它使子类更容易定义自己的属性并使用由ObservableCollection<T>
实现的OnPropertyChanged
方法.但这是主要原因吗?
One reason I can think of is that it makes it easier for subclasses to define their own properties and use the OnPropertyChanged
method implemented by ObservableCollection<T>
. But is this the main reason?
推荐答案
在属性Item
,Items
和Count
中,只有Item
实际上具有setter,因此无需覆盖Count
,因为您无法设置它们,所以无需从中引发事件.它们仅响应其他方法(例如Add
或Remove
)而更改,而那些方法将引发必要的属性更改事件(实际上,如果您查看源代码,ObservableCollection<T>
不会) t要么覆盖这些方法,要么覆盖基类中Add
和Remove
调用的protected
方法.
Of the properties Item
, Items
and Count
, only Item
actually has a setter, so there is no need to override Items
or Count
since you can't set them, there is no need to raise an event from it. They only change in response to some other method (like Add
or Remove
) and those methods will raise the necessary property changed events (actually if you look at the source, ObservableCollection<T>
doesn't override those methods either, but instead overrides protected
methods that are called by Add
and Remove
in the base class).
Now for Item
, the property isn't overriden, but if you look at the source for the SetItem
method:
/// <summary>
/// Called by base class Collection<T> when an item is set in list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void SetItem(int index, T item)
{
CheckReentrancy();
T originalItem = this[index];
base.SetItem(index, item);
OnPropertyChanged(IndexerName);
OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index);
}
您会从注释中注意到,设置了Item
时,基类会调用此方法,并且还会触发OnPropertyChanged
事件.
You'll note from the comment that this is called by the base class when an Item
is set and you'll also note that it fires off the OnPropertyChanged
event.
如果您查看源 Collection<T>
您可以确认是这种情况:
If you look at the source for Collection<T>
you can confirm that this is the case:
public T this[int index] {
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return items[index]; }
set {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if (index < 0 || index >= items.Count) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
SetItem(index, value);
}
}
因此,总而言之,Collection<T>
中的Item
调用在ObservableCollection<T>
中被覆盖的SetItem
,从而触发PropertyChanged
事件.
So in summary, Item
in Collection<T>
calls SetItem
that is overridden in ObservableCollection<T>
which triggers the PropertyChanged
event.
这篇关于为什么ObservableCollection< T>实现INotifyPropertyChanged?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!