2 反射代码中具有相同名称的事件?

发布于 2024-08-15 02:08:37 字数 572 浏览 10 评论 0原文

我在 Silverlight 中从事一个项目,我想知道 ObservableCollection 是如何工作的。我很惊讶地在 Reflector 中看到这一点:

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;
...

它怎么会有两个具有相同名称和类型的事件?这是怎么回事?这是 Reflector 中的错误吗?

I work on a project in Silverlight and I wanted to know how does the ObservableCollection work. I was quite surprised to see this in Reflector:

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;
...

How can it have 2 events with the same name and type? Whats going on? Is this a bug in Reflector?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

话少情深 2024-08-22 02:08:37

不,这是显式接口实现。此行:

protected event PropertyChangedEventHandler PropertyChanged;

无法实现 INotifyPropertyChanged 合约,因为它不是公开的。其他类无法引用它,因此 ObservableCollection 不会像它实现其所说的接口那样看待其客户端。例如,

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

为了解决这个问题,ObservableCollection 添加了 PropertyChanged 的​​另一个实现,该实现的“作用域”为 INotifyPropertyChanged 接口。也就是说,仅当客户端通过 INotifyPropertyChanged 类型的引用访问 ObservableCollection 时它才可用,在这种情况下它实际上是公共的。因此,现在想要使用 ObservableCollection 实现 INotifyPropertyChanged 这一事实的客户会很高兴,因为他们正在寻找的事件就在那里:

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

但是添加的 PropertyChanged 不会与同名的受保护成员冲突,因为它的作用域是 < code>INotifyPropertyChanged. 前缀。

No, this is explicit interface implementation. This line:

protected event PropertyChangedEventHandler PropertyChanged;

can't implement the INotifyPropertyChanged contract, because it's not public. Other classes can't refer to it, so the ObservableCollection doesn't look to its clients like it implements the interface it says it does. E.g.

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

To get around this, ObservableCollection adds another implementation of PropertyChanged, which is "scoped" to the INotifyPropertyChanged interface. That is, it's available only if a client accesses the ObservableCollection via a reference of type INotifyPropertyChanged, in which case it's effectively public. So now clients who want to use the fact that ObservableCollection implements INotifyPropertyChanged will be happy, because the event they're looking for is there:

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

But the added PropertyChanged doesn't conflict with the protected member with the same name because it's scoped with that INotifyPropertyChanged. prefix.

流年已逝 2024-08-22 02:08:37

这称为显式声明。这与泛型集合可以有两个 GetEnumerator() 方法相同。一个被宣布为公开的;另一个被声明为显式。

It's called an explicit declaration. It's the same way that a generic collection can have two GetEnumerator() methods. One is declared as public; the other is declared as explicit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文