Interfaces using IDisposable

Regarding IDisposable

I am creating an interface that I would expect to use system resources most of the time, but not always. Would it be reasonable to expect usage to include IDisposable in my interface?

For example, I have an interface that provides an average value for synchronizing with.

 interface IDateTimeProvider : IDisposable { int LeapSeconds {get;set;} DateTime LocalNow {get;} DateTime UtcNow {get;} DateTime GpsNow {get;} } class NtpTimeProvider : IDateTimeProvider { // Assume client is setup and ready to use. // Obtains time via network resources NtpClient client; NtpTimeProvider (int leapSeconds) { LeapSeconds = leapSeconds;} int LeapSeconds {get;set;} DateTime LocalNow {get{return client.Utc};} DateTime UtcNow {get{return client.Utc};} DateTime GpsNow {get{return client.Utc - TimeSpan.FronSeconds(LeapSeconds);}} void Dispose() { if(client != null) Client.Dispose(); } } class SystemTimeProvider : IDateTimeProvider { SystemTimeProvider (int leapSeconds) { LeapSeconds = leapSeconds;} int LeapSeconds {get;set;} DateTime LocalNow {get{return DateTime.Now};} DateTime UtcNow {get{return DateTime.UtcNow };} DateTime GpsNow {get{return DateTime.UtcNow - TimeSpan.FronSeconds(LeapSeconds);}} void Dispose() { //obviously this isn't needed} } 

So the question is, should I impose the IDisposable requirement when I expect most implementations to use the system resources that should be released? I am currently doing just that, since it is easier when the IDateTimeProvider user frees up resources and

 if(myDateTimeProvider is IDisposable) ((IDisposable)myDateTimeProvider).Dispose(); 

will not need.

+1
design-patterns idisposable
Mar 29 '13 at 16:15
source share
3 answers

So the question is, should I impose the IDisposable requirement when I expect most implementations to use the system resources that should be released?

This is controversial, but there are examples within the framework that follow these recommendations. A good example is Stream - it implements IDisposable , although there are subclasses where this is not needed.

I would carefully take care that this requires your users if you are really not sure that almost all implementations will require IDisposable , and not just some of them.

+1
Mar 29 '13 at 16:16
source share

As a rule, the reason for providing an interface is that programmers can consider different implementations of the concept as having the same set of rules. If you implement IDisposable only in classes that manage system resources, you force programmers to work with this implementation detail, adding complexity and fragility to your design.

If it is likely that your application will reference unmanaged resources when the object expires, you must absolutely implement the IDisposable interface so that consumers in your class can use the Dispose pattern to release these resources in a predictable way.

As a reminder of the reason for the Dispose Pattern:

In computer programming, a layout pattern is a design pattern that is used to process cleaning resources in runtime environments that use automatic garbage collection. The main problem that the layout template faces is that since objects in the garbage collection have finalizers rather than destructors, there is no guarantee that the object will be destroyed at any deterministic point in time. The dispose pattern works around this, providing the object with a method (usually called Dispose or similar) that frees up any resources the object holds onto.

http://en.wikipedia.org/wiki/Dispose_pattern

+1
Mar 29 '13 at 16:16
source share

The question of $ 50,000 is whether the code will ever be able to acquire ownership of objects that implement the interface without knowing their specific type and whether they require cleaning. In situations where this may happen [the quickest common examples are IEnumerable.GetEnumerator() and IEnumerable<T>.GetEnumerator() , although there are many other examples], the client code must use one of two patterns:

  • If the interface type does not implement IDisposable [as in the case of a non-generated IEnumerator returned by a non-shared IEnumerable ], then correctly written client code that acquired the ownership of the object must - before abandoning it - check to see if a specific object is being implemented, implements the interface, IDisposable and, if so, call its implementation IDisposable.Dispose .

  • If an interface implements IDisposable , a correctly written client that has acquired ownership must - before abandoning the object - call IDisposable.Dispose on the object if it somehow does not know that the object does not actually need to be cleaned. Note that even if an object does nothing in its IDisposable.Dispose method, in many cases it will be faster to name it unconditionally than to spend some considerable time determining whether a call is necessary. Even if only 0.001% of instances of objects need to be cleaned, including IDisposable will not transfer any new obligations to the client. Rather, it will increase the likelihood that the client code will fulfill its obligations and reduce the cost of this for all objects, including 99.999% of cases that do not require cleaning.

If the interface is unlikely to ever be returned by factory methods and will not be used in any other scenario, when the owner of the object does not know if cleaning is required, there is no need for an interface to implement IDisposable . But for cases when an interface type can be returned by factory methods, it must implement IDisposable .

+1
Apr 01 '13 at 17:12
source share



All Articles