![](/img/trans.png)
[英]How does ObservableCollection<T> implement INotifyPropertyChanged as protected?
[英]Why does ObservableCollection<T> implement INotifyPropertyChanged?
在.NET 4.0中,沒有ObservableCollection<T>
定義的單個屬性,也沒有覆蓋其父級或接口的任何屬性。 那么,為什么ObservableCollection<T>
實現INotifyPropertyChanged
?
我能想到的一個原因是,它使子類更容易定義自己的屬性並使用由ObservableCollection<T>
實現的OnPropertyChanged
方法。 但這是主要原因嗎?
同時通知Count
和Item[]
更改。 這是一個示例(僅使用C#6進行字符串插值):
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
class Test
{
static void Main(string[] args)
{
var collection = new ObservableCollection<string>();
((INotifyPropertyChanged)collection).PropertyChanged += (sender, e) =>
{
Console.WriteLine($" {e.PropertyName} changed");
};
Console.WriteLine("Adding");
collection.Add("Item");
Console.WriteLine("Adding");
collection.Add("Other item");
Console.WriteLine("Removing");
collection.RemoveAt(0);
Console.WriteLine("Changing");
collection[0] = "Different";
}
}
輸出:
Adding
Count changed
Item[] changed
Adding
Count changed
Item[] changed
Removing
Count changed
Item[] changed
Changing
Item[] changed
在屬性Item
, Items
和Count
,只有Item
實際上有一個setter,因此無需覆蓋Items
或Count
因為您無法設置它們,因此無需從中引發事件。 它們僅在響應某些其他方法(例如Add
或Remove
)時發生更改,並且那些方法將引發必要的屬性更改事件(實際上,如果您查看源代碼, ObservableCollection<T>
也不覆蓋這些方法,而是覆蓋protected
基類中Add
和Remove
調用的方法)。
現在,對於Item
,該屬性不會被覆蓋,但是如果您查看SetItem
方法的源代碼 :
/// <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
事件。
如果查看Collection<T>
的來源 ,則可以確認是這種情況:
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
事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.