1

C# についての私の理解では、そのメソッドが仮想としてマークされていない限り、サブクラスはメソッドの親の実装をオーバーライドできないということです。サブクラスが、virtual とマークされていない親メソッドと同じ名前のメソッドを宣言する場合、単にそのメソッドを非表示にします。そのため、メソッドが親型の参照から呼び出された場合、親メソッドが呼び出されます。サブクラス型の参照から呼び出され、サブクラス メソッドが呼び出されます。ただし、C# ライブラリで、この動作を妨げているように見える状況が見つかりました。

Collection<T>メソッドを宣言しますpublic void Add(T item)。このメソッドは仮想ではないため、サブクラスの実装でその動作をオーバーライドしないでください。ただし、次のテストでは矛盾した結果が得られます。

public void Test()
{
    ObservableCollection<String> strings1 = new ObservableCollection<String>();
    strings1.CollectionChanged += OnCollectionChanged;
    strings1.Add("One String");
    Collection<String> strings2 = strings1;
    strings2.Add("Another String");
}

public void OnCollectionChanged(Object source, 
    NotifyCollectionChangedEventArgs e)
{
    Console.WriteLine("Collection Change!");
}

動作はクラスにNotifyCollectionChanged実装されておらず、クラスはクラスのメソッドをオーバーライドできないため、コレクション変更イベントは、オブジェクトが として参照されたときではなく、として参照されたときにのみ発生すると予想されます。ただし、2 つのイベントが発生します。結果は次のとおりです。CollectionObservableCollectionAddCollectionObservableCollection<String>Collection<String>

Collection Change!
Collection Change!

ここで何が起こっているのか誰でも説明できますか?

4

2 に答える 2

1

ObservableCollectionには、独自のAddメソッドがありません。代わりに、CollectionクラスAddに依存します。つまり、次のようになります。

public class Collection<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
   {
     public void Add(T item)
     {
          if (this.items.IsReadOnly)
            ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
          this.InsertItem(this.items.Count, item);
     }

     protected virtual void InsertItem(int index, T item)
     {
          this.items.Insert(index, item);
     }     
  }

また、InsertItemは、ObservableCollectionでオーバーライドされる仮想メソッドです。

  public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
  {
    protected override void InsertItem(int index, T item)
    {
      this.CheckReentrancy();
      base.InsertItem(index, item);
      this.OnPropertyChanged("Count");
      this.OnPropertyChanged("Item[]");
      this.OnCollectionChanged(NotifyCollectionChangedAction.Add, (object) item, index);
    }
}
于 2013-03-18T06:06:25.560 に答える
0

ObservableCollection < T> は Collection < T > から派生し、通知イベントは、ObservableCollection クラスで定義されているハンドラーが割り当てられている場所で処理されます。コレクションの Add メソッドは、仮想で ObservableCollection クラスでオーバーライドされる Insert メソッドを呼び出します。オーバーライドされたメソッドは、イベント ハンドラーを呼び出します。

于 2013-03-18T06:10:52.920 に答える