C#可识别的问题
我有以下代码示例:C#可识别的问题,c#,interface,disposable,C#,Interface,Disposable,我有以下代码示例: public interface IRepository { // Whatever } public class SampleRepository : IRepository { // Implements 'Whatever' } public class NHibernateRepository : IRepository, IDisposable { // ... public void Dispose() { ... } } 现在-
public interface IRepository {
// Whatever
}
public class SampleRepository : IRepository {
// Implements 'Whatever'
}
public class NHibernateRepository : IRepository, IDisposable {
// ...
public void Dispose() { ... }
}
现在-这真的很糟糕吗?我不确定,但这似乎与不在C++
中标记基类的析构函数非常相似
我不想让IRepository
接口实现IDisposable
,因为这会带来不必要的复杂性和大量的类,这些类也必须实现IDisposable
该如何处理该案件? 我确信这可能发生在任何类型层次结构上——当其中一个派生类型必须管理可支配资源时 那么我应该怎么做呢?将
IDisposable
拉到第一个界面,或者让它保持原样,希望用户能够区分一次性和非一次性存储库
谢谢。这对我来说似乎很好。有什么问题吗?不,不要“向上拉IDisposable”。保持接口原子化、简单和独立
除非你能辩称可识别性是IRepository的一个基本特征(SamplerRepository表明并非如此),否则两者之间不应该有任何区别 您可能遇到的唯一问题是,您是否正在使用某种类型的工厂、控制反转或依赖项注入模式/框架。如果要将对象用作接口,则永远无法执行以下操作:
IRepository repo = Factory.GetRepository();
repo.Dispose();
您可能希望引入一个实现IDisposable的INHibernateRepository。因为IDisposable通常是一个低级操作,所以让您的接口实现这个接口并没有什么大问题。是的,我认为这很糟糕——因为您不能以相同的方式使用所有存储库 我个人会让存储库接口扩展
IDisposable
——毕竟,在没有操作的情况下实现它是很容易的
这与主框架中的Stream
、TextReader
和TextWriter
所做的选择完全相同<代码>StringWriter(例如)不需要处理任何东西。。。但是TextWriter
仍然是一次性的
这一切之所以发生,是因为
IDisposable
在某些方面是一个奇怪的接口:它不传递提供给调用者的东西。。。它传达了来电者所需要的信息(或者,如果你不同意,至少会强烈鼓励你提出可能的问题)。首先,回答你的问题。处置模式不同于C++析构函数。Dispose
方法旨在处置类所包含的资源,而不是处置类本身
< >将C++析构函数标记为<代码>虚拟< /> >的原因不存在于.NET中,因为引用类型的每个实例都有一个包含运行时类型信息的同步块。使用此方法,垃圾收集器可以适当地回收正确的内存量
至于使用IDisposable
扩展IRepository
,这将是一个在绝大多数情况下都可以接受的快速解决方案。我能看到的唯一反对意见是,扩展接口将需要所有派生类来实现接口。从表面上看,用NOPs实现一个接口似乎很容易(可能多次),但您不应该这样做。但是,我可以提供另一种选择
取而代之,考虑使用一个实现配置模式的抽象基类。这将遵循dispose模式的“标准”实现的结构
public abstract class Repository : IDisposable
{
public void Dispose() { Dispose(true); }
protected virtual Dispose(bool disposing) { }
}
public class NHibernateRepository : Repository { /* Impl here, add disposal. */ }
public class TestRepository : Repository { /* Impl with no resources */ }
请看一看Microsoft编写的,以查看更详细的示例。您所描述的内容与一个重要的但书是一致的:添加了“IDisposable”到其基的类型的对象决不能传递给使用者,而该使用者可能最终持有或保留该对象一段未知的时间 基本上,IDisposable对象的所有者必须(*)处理对象本身,或者将对象交给能够接受并履行责任的新所有者。最初,IDisposable对象通常由其创建者“拥有”,但移交是常见的。对IDisable对象的引用可以在不转移所有权的情况下提供给另一个对象;在该场景中,当不再需要对象时,所有者仍负责处理该对象。为了实现这一点,所有者必须知道不再需要该对象。最常见的模式是:
如果这些模式中有一种适用,你可能会处于良好状态。如果没有,您可能会遇到麻烦。+1确切地说,如果需要,您还可以添加
新的public void Dispose()
。+1,因为您不能以相同的方式使用所有存储库和良好的示例。然而,Stream和TextWriter是不会强制继承者实现处置逻辑的类。我认为抽象基类在这里更合适。@Matt:有一个抽象基类可能更合适,是的-可能除了接口之外。当使用者“不确定”时,围绕这些IDisposable实例的创建来实现工厂,这算是一个好的解决方案吗如何/何时处置,并让工厂跟踪实例,然后在需要时处置它们?50000美元的问题是是否属于cr