2009-12-20 5 views
0

Je travaille sur un projet dans Silverlight et je voulais savoir comment fonctionne ObservableCollection. J'ai été très surpris de voir ce réflecteur:2 Evénements avec le même nom dans le code Reflectored?

public class ObservableCollection<T> : 
      Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged 
{ 
    // Fields 
    private bool _busy; 

    // Events 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    protected event PropertyChangedEventHandler PropertyChanged; 

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged; 
... 

Comment peut-il avoir 2 événements avec le même nom et le type? Que se passe-t-il? Est-ce un bug dans Reflector?

Répondre

2

Non, ceci est explicit interface implementation. Cette ligne:

protected event PropertyChangedEventHandler PropertyChanged; 

Impossible d'implémenter le contrat INotifyPropertyChanged, car il n'est pas public. Les autres classes ne peuvent pas s'y référer, donc ObservableCollection ne regarde pas ses clients comme il implémente l'interface qu'il dit faire. Par exemple.

ObservableCollection<string> coll; 
// ObservableCollection implements INotifyPropertyChanged, so I should be able to... 
coll.PropertyChanged += ... 
// ... but this wouldn't compile because PropertyChanged is protected 

Pour contourner ce problème, ajoute ObservableCollection une autre mise en œuvre de PropertyChanged, qui est "scope" à l'interface INotifyPropertyChanged. C'est-à-dire qu'il n'est disponible que si un client accède à ObservableCollection via une référence de type INotifyPropertyChanged, auquel cas il est effectivement public. Alors maintenant, les clients qui veulent utiliser le fait que ObservableCollection implémente INotifyPropertyChanged sera heureux, parce que l'événement qu'ils recherchent est là:

INotifyPropertyChanged notifier = coll; 
notifier.PropertyChanged += ... // compiles (using explicit implementation) 

Mais le PropertyChanged ajouté ne pas en conflit avec l'élément protégé par la même nom parce qu'il porte le préfixe INotifyPropertyChanged..

0

C'est ce qu'on appelle une déclaration explicite. C'est la même manière qu'une collection générique peut avoir deux méthodes GetEnumerator(). L'un est déclaré public; l'autre est déclaré comme explicite.

Questions connexes