我最近实现了一个类:

class TestClass : IDisposable
{
    RegistryKey m_key;
    public TestClass()
    {
        m_key = Registry.CurrentUser.OpenSubKey("Software", false);
    }

    public void Dispose()
    {
        // m_key.Dispose();
        IDisposable disp = m_key;
        disp.Dispose();
    }
}

如果我取消对Dispose的直接调用,我会收到错误CS0117(<!> quot;'Microsoft.Win32.RegistryKey'不包含'Dispose'<!>的定义;)。一些谷歌搜索引导我这个主题,在那里我学到了正在发生的事情,所以我现在了解它的机制。 MSDN 文档表明作者更喜欢我调用Close()而不是Dispose(),但不解释原因。

这种模式的目的是什么(我认为我在IO类中也看到了它)?鉴于这是班级作者的故意决定,上面的代码有多糟糕(通过IDisposable接口调用Dispose)?它不会太糟糕 - 毕竟,这是在使用声明中会发生什么,对吧?

[编辑:1]从<!>更改标题;非公开<!> to <!> quot; explicit <!> quot; 2)从我的代码中删除了显式实现,意外地从实验中留下了]

有帮助吗?

解决方案

这称为显式接口实现。在您的示例中,因为您将Dispose()方法定义为<!>; void IDisposable.Dispose()<!> quot;你也明确地实现了IDisposable接口。

这通常是为了避免碰撞。如果Microsoft想要添加另一个为RegistryKey做其他事情的Dispose()方法,除非他们使用该接口的显式实现,否则他们将无法做到。

通常使用通用的IEnumerable <!> lt; T <!> gt;接口。它还要求您还实现非通用接口IEnumerable。这两个接口中唯一的成员是GetEnumerator,通用的一个更有用,所以它通常像这样实现:

public clas SomeClass : IEnumerable<SomeOtherClass>
{
    public IEnumerator<SomeOtherClass> GetEnumerator ()
    {
        ...
    }

    IEnumerator IEnumerable.GetEnumerator ()
    {
        return GetEnumerator ();
    }
}

这种方式当你调用SomeClass的GetEnumator方法的对象时,它调用泛型版本,因为另一个是明确实现的,允许我们获得强类型泛型允许。

见Jesse Liberty的编程C#第166-169页(我已经有了第四版)。

其他提示

大多数人不同意我的意见,但我喜欢使用所有接口的显式接口实现。我想说清楚我是在写一个方法来调用我的对象还是我的界面。

如果你有一个对象的引用并且想要调用一个接口方法(如上面的例子),这很痛苦,但我通过编写来缓解它:

class C : IDisposable
{
    public IDisposable IDisposable { get { return this; } }
    void IDisposable.Dispose() { }
}

这意味着在C上调用方法看起来像:

C c = ...
c.IDisposable.Dispose();

编译器将其解析为<!>“;在C上调用IDisposable属性,然后在结果<!>上调用Dispose()方法。但我把它读成<!>“;在IDisposable.Dispose() <!>上调用C方法这似乎很自然。

遗憾的是,这种方法在使用通用接口时会变得很丑陋。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top