3

标题很清楚地解释了这个问题。我想知道为什么要实现 IDisposable 接口,它在一个类中只提供一个方法定义,而在另一个类中,我可以显式定义一个 dispose() 方法并释放所有非托管资源。

说我有这两个课

class MyClass : IDisposable
{
    public void Dispose() { }
}

class MyClass2
{
    public void Dispose() { }
}

MyClass 和 MyClass2 之间到底有什么区别?

4

4 回答 4

10

这个例子中一个非常具体的结果,特定于IDisposable,是第一个类可以在using() {}语句中使用,而第二个不能:

using (var c1 = new MyClass())  { ... }  // Ok
using (var c2 = new MyClass2()) { ... }  // Error

更一般的答案是接口提供了一个允许替换的契约。搜索“接口的好处”或类似内容以获取更多信息。例如,这个 SO 答案有一个列表。

替换示例:

public interface IRepository { ... }

public class RealRepository : IRepository { ... }
public class MockRepository : IRepository { ... }

class MyController { public IRepository { get; set; }

这个(粗略的)片段显示了一个可以与真实(Db)存储库一起使用并使用模拟存储库进行测试的控制器。

于 2013-06-13T11:39:55.283 回答
3

因为IDisposable定义了一些用于释放资源的常规语义的通用契约。这是一种已知的模式,可以依赖它来公开执行特定操作的相关方法(Henk 用语言给出了一个具体的例子using)。只有您的代码的直接用户知道您的类Dispose方法的存在。

在您的第一个实例中,该类实现了合同,并且可以以常规方式使用。

于 2013-06-13T11:39:01.913 回答
1

IDisposable 只是一个接口,但问题可能被概括为“当我可以简单地实现方法时,为什么要实现接口?”。这是另一个可能会有所启发的示例:在使用类时它很重要。

interface IAnimal
{
    void PutInZoo(Zoo);
}

class Cat: IAnimal
{
    public void PutInZoo(Zoo theZoo);
}

class Fish
{
   public void PutInZoo(Zoo theZoo);
}

class Zoo
{
    public void PutInZoo(IAnimal animal)
    {
         animal.PutInZoo(this);
    }

    public Zoo()
    {
         this.PutInZoo(new Cat());  // Ok
         this.PutInZoo(new Fish()); // Nope, Fish doesn't implement IAnimal
    }
}

除了编译错误之外,实现接口最突出的副作用是,如果接口发生变化,您必须遵守它。

在此示例中,如果IAnimal更改其定义PutInZoo并重命名为FreeFromZoo,Fish仍会编译(并且可能会破坏其使用者)但Dog不会:它不再实现IAnimal.

于 2013-06-13T12:03:33.880 回答
0

两者的区别只是Class1官方实现了接口。

Class2 只是潜在地实现了它,尽管这些术语不是很好;两种方法的实现/存在可能相同。

于 2013-06-13T11:55:17.420 回答