【问题标题】:Explicitly implement interface of unchangeable base class显式实现不可更改基类的接口
【发布时间】:2014-03-26 16:30:49
【问题描述】:

首先,这个问题与How to call an explicitly implemented interface-method on the base class 非常相似,但又不一样。

我的问题是,我什至无法向相关基类添加任何辅助方法来解决该问题中解决的问题。

代码:

class AsyncObservableCollection<T> : ObservableCollection<T>
{

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new ThreadSafeEnumerator<T>(this.GetEnumerator(), this.mutex);
    }
}

其中ObservableCollection&lt;T&gt; 来自Collection&lt;T&gt;,它实现了IEnumerable&lt;T&gt;

编译错误:

AsyncObservableCollection<T>.IEnumerable<...>.GetEnumerator()': 
containing type does not implement interface 'System.Collections.Generic.IEnumerable<T>

问题:

所以我的目标是让任何 foreach 循环使用我的 AsyncObservableCollection&lt;T&gt; 的实例来获取我的自定义枚举器,同时在我的自定义方法中允许 this.GetEnumerator() 仍然获得“标准”枚举器。我不确定最好的方法是什么。

【问题讨论】:

    标签: c# interface overriding base enumerator


    【解决方案1】:

    您只需要明确声明该类实现了该接口。不要依赖基类实现它的事实:

    class AsyncObservableCollection<T> : ObservableCollection<T>, IEnumerable<T>
    

    话虽如此,作为一个好的设计问题,我建议不要让隐式接口实现与其他实现完全不同。相反,您应该有一个方法/属性来获取“其他”版本,或者甚至可能是两个迭代器,以便调用者在它们的迭代语义不同时非常清楚。 (最重要的是,它允许用户使用带有 foreach 循环的任一类型的语义,而不是手动迭代迭代器以获得不同的语义。

    【讨论】:

    • 感谢 Servy,我将您的答案标记为正确,因为它现在看起来可以工作了。不过,我对您对最佳实践的建议很感兴趣;我没有想过保护用户不被滥用。我真的不希望线程不安全的“标准”枚举器被公开。我只希望线程安全的包装器枚举器可以公开访问(并由 foreach 等使用)。此外,我真的不希望他们手动迭代自定义迭代器,因为他们可能忘记调用结束锁定的 ThreadSafeEnumerator.Dispose()。我得再做一些工作,谢谢。
    猜你喜欢
    • 2018-02-08
    • 2023-03-12
    • 2016-07-22
    • 2012-12-04
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多