Consider a "disposable" keyword in C# - c#

What are your opinions on how disposable objects are implemented in .Net? And how do you solve the repetitiveness of implementing IDisposable classes?
I feel that IDisposable types are not the first-class citizens that they should've been. Too much is left to the mercy of the developer.
Specifically, I wonder if there should'nt have been better support in the languages and tools to make sure that disposable things are both implemented correctly and properly disposed of.
In C# for instance, what if my class that needs to implement the disposable semantics could be declared like this:
public class disposable MyDisposableThing
{
~MyDisposableThing()
{
// Dispose managed resources
}
}
The compiler could in this case easily generate an implementation of the IDisposable interface. The destructor ~MyDisposableThing could be transformed into the actual Dispose method that should release managed resources.
The intermediate C# code would look like this:
public class MyDisposableThing : IDisposable
{
private void MyDisposableThingDestructor()
{
// Dispose my managed resources
}
~MyDisposableThing()
{
DisposeMe(false);
}
public void Dispose()
{
DisposeMe(true);
GC.SuppressFinalize(this);
}
private bool _disposed;
private void DisposeMe(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Call the userdefined "destructor"
MyDisposableThingDestructor();
}
}
_disposed = true;
}
}
This would make for much cleaner code, less boilerplate disposing code, and a consistent way of disposing managed resources. Implementing IDisposable by hand would still be supported for edge cases and unmanaged resources.
Ensuring that instances are properly disposed is another challenge. Consider the following code:
private string ReadFile(string filename)
{
var reader = new StreamReader();
return reader.ReadToEnd(filename);
}
The reader variable never outlives the scope of the method but would have to wait for the GC to dispose it. In this case, the compiler could raise an error that the StreamReader object was not explicitly disposed. This error would prompt the developer to wrap it in a using statement:
private string ReadFile(string filename)
{
using (var reader = new StreamReader())
{
return reader.ReadToEnd(filename);
}
}

An oft-stated principle is that "design patterns are needed to address language deficiencies". This is an example of that principle. We need the disposable pattern because the language doesn't give it to you.
I agree that disposability could have been elevated out of the "pattern" world and into the C# language proper, as we did with, say, property getters and setters (which are standardizations of the pattern of having getter and setter methods), or events (which standardize the idea of storing a delegate and calling it when something interesting happens.)
But language design is expensive and there is a finite amount of effort that can be applied to it. Thus we try to find the most useful, compelling patterns to put into the language proper. And we try to find a way that does so in a way that is not merely convenient, but actually adds more expressive power to the language. LINQ, for example, moves the concepts of filtering, projecting, joining, grouping and ordering data into the language proper, which adds a lot of expressive power to the language.
Though this is certainly a good idea, I don't think it meets the bar. It would be a nice convenience, I agree, but it doesn't enable any really rich new scenarios.

In addition to the other answers, there is the problem of how much should this implement and what should people expect from it? Say I declared my class like this:
public disposable class MyClass
{
readonly AnotherDisposableObject resource = new AnotherDisposableObject();
~MyClass()
{
this.resource.Dispose();
}
public void DoStuff()
{
this.resource.SomeMethod();
}
}
Then what would you expect to happen if a caller called DoStuff after the instance had been disposed? Should the compiler automatically insert something like
if (this.disposed) throw new ObjectDisposedException();
at the start of every method because you have declared the class as disposable?
If so then what about cases where methods are explicitly allowed to be called after an object is disposed (e.g. MemoryStream.GetBuffer)? Would you have to introduce a new keyword that indicated this to the compiler, e.g. public useafterdispose void ...?
If not then how do you explain to people that the new keyword implements some of the boiler-plate code for you, but that they still need to write code to check whether the object is disposed in each method? Moreover, how can they even check this, because all the state information about whether the object has been disposed is auto-generated! Now they need to track their own flag in the ~MyClass method which undoes half the work the compiler should be doing for you.
I think as a specific language pattern there are too many holes in the concept, and it only attempts to solve one specific problem. Now what could solve this entire class of problem in a general-purpose fashion is mixins (i.e. a Disposable mixin) and this language feature would be generally reusable for different concepts (e.g. Equatable mixin, Comparable mixin, etc.). That's where my money would go.

Personally, I consider the support for IDisposable to be quite decent in the current version of .NET. The presence of the using keyword pretty much makes it into a first-class construct for me.
I do admit there is a certain amount of boilerplate code involved, but not enough to warrant a new language features. (Auto-implemented properties was a good example of a feature that was begging to be introduced.) You've missed out an important point in your post that this "boilerplate" code is not always what you need. Mainly, you need to dispose unmanaged resources outside of the if (disposing) block.
Of course, the destructor (~MyDisposableThing) and parameterless Dispose() method are genuinely boilerplate and could be eliminated by the user of a language keyword, as you suggest - but again I'm not sure the introduction of an actual new keyword is all that necessary for a few lines of code.
I certainly see the point you are making here, and do sympathise with it to some degree. (I'm sure no coder would complain if your suggestion becamse part of the language specification.) However, it's not likely to convince the .NET development team when there are a rather limited number of lines of code anyway, some of which are arguably fairly context-specific (and thus not boilerplate).

I completely agree that IDisposable needs better language suppprt. Here's my variant of it from a while ago. The details are probably wrong, but C++/CLI serves as a pretty good model for this. Unfortunately it confuses the hell out of C# programmers when I show them examples in C++/CLI. But it already does "the right thing" in terms of implementation; we would just need a new syntax in C#.
Even the simplest Windows Forms application has a Dispose method in it, which is generated by a wizard and is fragile in the face of inexpert changes. The idea of composing components together such that one component can "own" several others is so fundamental that IDisposable is practically unavoidable, and unfortunately it seems to take several pages of most books to explain how to implement it correctly.
The existing using statement takes care of the client side. Where we need more language support is on the implementation side.
Some of the fields of a class are references to things that the class "owns", and some not owned. So we have to be able to mark a field as owned.
Also, it would be a very bad idea to automatically generate a finalizer. Most often, a class will own other objects that implement IDisposable. Not all classes are thread safe, nor should they need to be. If they are called from a finalizer, that happens on another thread, forcing them to be thread safe. This is probably the one area around IDisposable that causes the most confusion - a lot of people read the books and come away with the mistaken impression that you have to write a finalizer on an object that supports IDisposable.

I realize this is an old thread but there is something that has been overlooked.
Dispose pattern in both C# and Java break the fundamental reason for not having a deterministic destructor.
MyObject A = new MyObject()
MyObject B = A;
A.Dispose();
What is the state of B now? What if the owner of B didn't really want it disposed. You now have the same issue in C++ where you have to keep track of all the references of objects you are holding on to.
IDisposable is only truly valid within the context of using() and ensuring resource cleanup if an exception occurs.
There are design patterns to do this but it isn't IDisposable
#Peter Yes I am arguing that the Dipsosable pattern has a fault. When implemented the Disposable pattern isn't normally meant to just dispose OS resources with the idea of being able to continue using the object that was disposed. By using the Disposable pattern outside of a try{} finally{} in Java or using() in .NET you break one of the reasons of having a GC. I am not saying memory will leak. I am saying you can now have other parts of the code that have a reference to an Object that has been disposed. Now the onus is back on the developer to check if an object has been disposed before each call, or at the very least catch a ObjectDisposedException.
Lets look at a silly example:
FileStream stream = new FileStream (#"c:\mylog.txt");
logger.setStream (stream);
Who is supposed to invoke .Dispose()? It may not be obvious that the logger is now aquiring ownership of the file stream. Let's say the stream was created somewhere else outside of the developer knowing it will be set as the logging stream.
if we were to add one line, we would break the logger
using (FileStream stream = new FileStream (#"c:\mylog.txt"))
{ logger.setStream (stream); }
or
FileStream stream = new FileStream (#"c:\mylog.txt");
logger.setStream (stream);
stream.Dispose();
The Disposable pattern does not reference count for resources. The developer now has to be conscious of who owns the object and who is responsible for cleaning it up. The real problem is that when Dispose() is invoked the normal behavior is to invalidate the whole object preventing it from being used.

IMHO, the .net languages have a major shortcoming in their handling of iDisposable, which is that there is no nice way of handling initializers that throw exceptions. Unless one 'leaks' a copy of the object under construction or the disposable objects therein, there's no way to clean up any iDisposable objects which were created (either in an initializer, or a base-level constructor) before an initializer throws.
Two features I would like to see toward that end:
A class declaration that would cause a particular method to be invoked if an exception throws out of its constructor.
A field declaration which would indicate that the field should have .Dispose called upon it if some special private method or keyword is used on the object.
BTW, I would also like to see a declaration available for structure methods which would indicate that the method alters the underlying structure. Use of such methods would be forbidden on structure rvalues, and use of such methods on structure properties would generate a read-modify-write sequence.

Okay you need to understand the difference between managed and unmanaged memory.
Put simply, c++ style destructors wouldn't work in the managed world of c# because there's no guarantee when the object gets garbage collected, hence you would never know when the destructor would get called, which would make things very unpredictable.
As opposed to c++, when destructors get called as soon as the class goes out of scope, so you can guarantee when it gets called.
This is the reason why c# can't have destructors.

Related

How to properly dispose locally created object in another method?

So I have a class which implements IDisposable, and I have several methods (in another class) which follow the pattern below:
public void SomeMethod()
{
DisposableObject disposableObject = new DisposableObject();
// Do some stuff with the object
SomeOtherMethod(disposableObject);
disposableObject.Dispose();
}
While all of these methods do different things, they all call SomeOtherMethod at the end, which does a few more things with the disposable object before it's no longer needed.
When I move disposableObject.Dispose(); into SomeOtherMethod, Visual Studio gives me a message saying:
"Use recommended dispose pattern to ensure that object created by 'new DisposableObject()' is disposed on all paths: using statement/declaration or try/finally"
This message appears regardless of whether or not I pass the disposable object to SomeOtherMethod using the ref keyword.
My question is, will that object be disposed as long as SomeOtherMethod calls Dispose() on it? I'm assuming it will, and Visual Studio continues to send the message simply because it isn't "aware" of what's happening to that object in subsequent methods, but I'd love to get some confirmation on that!
It may be disposed or may be not, depends on the fact whether the execution will reach the Dispose invocation or not and that's because an exception can be thrown before the Dispose is called. Using try finally construction explicitly or implicitly by using keyword ensures that it will be called for any scenario and that's why VS gives you the warning.
will that object be disposed
Sorry, but that’s a meaningless question. The CLR does not keep track of whether an object has had its “dispose” method called or not (see Will the Garbage Collector call IDisposable.Dispose for me? )
As a general rule, it is always much nicer (readable/ maintainable / less-bug-prone / etc) that a method that creates an issue should also be the one that cleans up after itself. As you’ve just found, this pattern also allows automated checking by the compiler - and again, it is also a good rule to ensure that your code compiles cleanly without errors OR WARNINGS.
In this case, the warning is giving you a couple of ways to implement this cleanly; personally, I would prefer the “using” clause (so avoiding having to have an explicit call to “dispose”) like :
public void SomeMethod()
{
using (DisposableObject disposableObject = new DisposableObject() )
{
// Do some stuff with the object
SomeOtherMethod(disposableObject);
}
}
No matter where one call the Dispose(), it is called.
Not using the language keyword using for the disposable pattern, therefore moving the dispose in another method, is an anti-pattern, therefore it is a bad practice and a source of potential problems.
You can only remove the warning by adding the warning number in the project build settings.
The method Dispose() doesn't destroy the object.
The dispose pattern is only for freeing unmanaged resources like windows handle and shared memories.
After a call to Dispose() you still have the object and so the reference to the object that remains referenced in the managed memory.
Dispose() is made to be called once time at the end of object usage and no more.
The compiler send you a warning because you break the standard behavior of the pattern usage that is to use the using keyword.
And breaking standards can be source of problems.
The using of disposable objects standard is made to avoid bugs by letting the compiler generates the try { ... } finally { Dispose() } block to be sure that Dispose() is correctly called in the right place to avoid mistakes.
So avoid calling the Dispose() directly.
Unless you are sure of what you do, prefer using:
public void SomeMethod()
{
using ( DisposableObject disposableObject = new DisposableObject() )
{
// Do some stuff with the object
SomeOtherMethod(disposableObject);
}
}
And your code may be robust.

How to dispose object

How to dispose my object? I am doing it by this. Whats is wrong? The Obj.Dispose() function does not appear to be right.
class MainclassForm : Form, IDisposeable
{
public void createanddispose()
{
A obj = new A();
obj.dowork();
obj.Dispose();//does not appear as a function
}
}
You can better use the using statement. Something like
using (MyIDisposableObject obj = new MyIDisposableObject())
{
// object here
}
A good reference to check on MSDN: Avoiding Problems with the Using Statement
The C# "using" statement results in a call to Dispose(). This is the
same as Close(), which may throw exceptions when a network error
occurs. Because the call to Dispose() happens implicitly at the
closing brace of the "using" block, this source of exceptions is
likely to go unnoticed both by people writing the code and reading the
code. This represents a potential source of application errors.
To call Dispose() on an object, your class must be inherited from IDisposeable interface and have an implementation of it:
class A : IDisposable
{
public void Dispose()
{
GC.Collect();
}
}
There are a couple things wrong here, but I believe the root is that you might confusing IDisposable with a Garbage Collector.
IDisposable is an interface that the type A, in your example, may implement. It that were the case, you could be sure that any instance of A had the method Dispose() you're looking for. This is useful for things like Streams, where they need to be closed, but it's not useful for (just as an example) a ComplexNumber type that has no outstanding resources.
In these cases, your managed C# code will handle all the "disposal" that needs to happen. It will get rid of the memory that object is using. That feature comes for free (sort of), and you don't need (or want) to do anything to explicitly invoke it. That's the main difference between managed (C#, Java, etc.) and unmanaged (C++) code.
Essentially, if an object is using more than just memory (like an open file does), IDisposable will be useful. If it is just memory (like a Form, or DateTime, or a majority of other things), there's no need for it.
As for your specific code, you've applied IDisposable to the type that contains your functions. Just as you couldn't call this.AddMinutes(1) to get at DateTime's method, you can't get at this one.
If you do need the added functionality of implementing IDisposable, you'll have to do it on A. Applying IDisposable, like any other interface, to MainclassForm will tell the compiler that you have a Dispose() method on that class, which is true only because the Windows Forms object has one. If it didn't, this would throw a compiler error, and you'd have to add one.

"using" keyword in C# with dataset

I have a small confusion with the IDisposable interface and the using keyword in C# on which classes we could use it.
using (DataSet studentDS = GetMyStudentDS())
{
// here comes some code
}
I found that Classes inherited from DataSet class are not finalized by the garbage collector, if so is it a good practice to put that in the using block so that it is done manually once its job is done. could someone brief it for the benefit of all. Thanks.
is it a good practice to put that in the using block
Yes it is. As DataSet implement IDisposible interface. DataSet extends MarshalByValueComponent class. MarshalByValueComponent class implements IDisposable.
Any derived type will also have IDisposable implemented. If it does not explicitly implements (in other words override IDisposable.Dispose), base method (DataSet.Dispose) will be called.
Regarding the Finalizer, that is a separate concept to make sure that unmanaged resources are cleaned up even if developer fails to call the Dispose method (or forgets using block).
I personally would not use it for a DataSet. I would use a using statement when I would need to close a connection and dispose of it, such as a file reader, database or a SharePoint connection. C# is a managed language and the CLR will take care of garbage collection for you and in a case such as using a DataSet I would still stick with this principle (Let the CLR do it for you).
http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx
http://www.w3enterprises.com/articles/using.aspx
There's a difference between a finalizer (destructor) and the IDisposable pattern. A finalizer is called by the GC at non-deterministic times and is used to clean unmanaged resources associated with the class and free the memory occupied by the instance. It is out of your control when the destructor runs.
IDisposable is used to clean objects at deterministic times. It doesn't free the memory occupied by the object but it is often used to close files, database connections, ...
So the general rule is that if an object implements IDisposable it is good practice to wrap its instances in using keyword in order to release resources as soon as possible.
DataSets implement IDisposable, but they supress their Finalization.
So it's really not needed, they do not introduce any unmanaged code.
Do not wrap it with a using statement, however don't forget to use the using keyword around your sql connection or data readers.
C# allows You to use using on everything that implements IDisposable. Why? Because using is just a syntactic sugar. using(obj){/*somecode*/} is actually something like this:
try
{
/*somecode*/
}
finally
{
if(obj!=null) obj.Dispose();
}
If You are using Typed DataSet You might have noticed that your autogenerated class does not override Dispose(bool). So Dispose does nothing to your autogenerated tables and columns.
To help your data set free memory (and it realy has problem with it) override Dispose(bool) in your autogenerated TypedDataSet (in partial file). Do something like this:
protected override void Dispose(bool disposing)
{
foreach (DataTable tab in this.Tables)
{
if (tab != null)
{
tab.Clear();
tab.Columns.Clear();
tab.Dispose();
}
}
this.Tables.Clear();
base.Dispose(disposing);
}
And now using using on this SataSet will make sense.
Yes, definitely you can use any object initialization code in using
block. There is no sideffects of using it. In, whatever scenario if
you want to make 100% sure for garbage collection of an object keep it
in using block.

What is this IDisposable doing for me?

I am working on a "learning program" and using the Code Rush refactoring tool with my learning. With the latest update of Code Rush it has been recommending implementing IDisposable to my programs. I know what MSDN says about IDisposable and I have a real basic understanding of what it does but because I don't know all the implications of implementing it I have been ignoring the recommendation. Today I decided to learn more about it and went along with the recommendation.
This is what it added to my program.
class Program : IDisposable
{
static Service _proxy;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (_proxy != null)
{
_proxy.Dispose();
_proxy = null;
}
}
~Program()
{
Dispose(false);
}
So my questions is this. Does that do everything I need to do to get the advantage of IDisposable or do I need to do something in code to make it work? I put a break points on that and never reached it through the debugger so either it was not needed or I am not using it the way it was intended. Can someone please shed some light on what this is doing for me or how I should use it so it does do something for me?
In this case, CodeRush is suggesting you implement IDisposable because your class encapsulates an IDisposable resource (it's seeing _proxy, though that's not entirely a good thing since it's static). Code Rush thinks that there is a type that you're using which should be explicitly cleaned up, but you're not providing a way to do it via your class.
That being said, IDisposable is tricky - and this is one case where the generated code is not really a good implementation (even if _proxy were an instance variable). I would recommend not using the destructor in this case. It will cause performance issues in the GC, and in this case, doesn't help with the safety, as the encapsulated resource should handle that the case where you forget to call Dispose() for you. For details, see my series on IDisposable, and, in particular, encapsulating an IDisposable class.
In addition, this class shouldn't implement IDisposable (unless there is some other reason to do so) given the code above, as the _proxy resource is static. Disposing a static resource from an instance is likely to cause problems, at least in a general case. (In this case, it's obviously not problematic, but it's not a good practice...) Typically, a static variable has a very different lifetime than an instance member, so automatically disposing of it would be inappropriate.
In a properly-written program, at any given time, for every object that could possibly have a meaningful implementation of IDisposable, there will be some entity that is responsible for ensuring that IDisposable.Dispose will get called on that object sometime between the last "real use" of that instance and its ultimate abandonment. In general, if an object Foo is going to hold references to objects which implement IDisposable, at least one of the following scenarios should apply:
Some other object will also hold the reference for at least as long as Foo needs it, and will take care of calling Dispose on it, so Foo should let the other object take care of the Dispose.
The object holding the reference will be the last thing to use the IDisposable object in question; if Foo doesn't call Dispose, nothing else will. In that scenario, Foo must ensure that that other object's Dispose method gets called once it (Foo) is no longer needed, and before it is abandoned. The most idiomatic way to handle this is for Foo to implement IDisposable.Dispose, and for its Dispose method to call Dispose on the IDisposable objects to which it holds the last useful references.
There are some scenarios where a class designer might not know whether its class is going to hold the last useful reference to an IDisposable object. In some cases, this issue may be resolved by having a class constructor specify whether a IDisposable passed to the constructor is being "lent" or "given". Other cases may require the use of reference-counting wrappers or other complex techniques.

Using specific patterns to implement interfaces

I have been very intriuged by design patterns lately, and specifically following correct design patterns in my classes that implement one or several interfaces.
Let's take an example. When a class implement IDisposable you should follow a specific pattern to make sure that your resources are properly cleaned up, by creating a private Dispose(bool disposing) method that differentiates between if it's called by the finalizer, or if it's called from the public Dispose method. Also, a finalizer should be implemented in this case, and you might also need a private bool variable called isDisposed that is set by the Dispose method, so that any method called after th object is Disposed will call a Exception making it clear that this object is already disposed, instead of the code inside the method crashing because some of the required resouces are disposed, and thereby no longer available.
There are also a lot of other interfaces I routinely implement, but it's not all of them I am sure if the way I implement them is the preferred way of doing it, and I might find out later on that it causes a subtle bug that is hard to find, that would probably have been non-existant if I had followed the proper pattern in the first place.
some examples of interfaces I would like to know the best way of implementing are ISerializable, IComparable, IComparable<>, ICloneable, IEnumerable<>, and so on. All interfaces from the Framework are interesting here, so it should not be limited to those I have listed above.
What I'm after is for different interfaces, the preferred way and hopefully also a link to resource on the internet that explains how and also why a specific pattern should be followed.
I hope to get a good collection of these patterns, as I know that they can greatly improve my code and make it more correct, and follow best-practices
It would be great if there are several patterns for the same interface so we can discuss which one is preferred. That might also cause some of you to maybe move over to a new pattern, or make modifications to your existing patterns to improve your code even further, and that would be great!
Edit
After reading Grzenios comment, I would also urge everyone to give the context the pattern should be applied for. For example the IDIsposable pattern should only be followed if you have some unmanaged resources inside your class that you need to dispose, and not if all the objects you need to dispose implements IDisposable themselves.
Edit 2
I should probably start this myself, since I put the question out here. So I'll describe one pattern I know well, and that is the IDisposable pattern.
This pattern should only be used if your class contain one or more unmanaged resources inside your class, and you hav eto make sure that they get Disposed. in this case in addition to the Dispose method we will need a finalizer in case the user of your class forget to dispose it.
So first thing first. Your class should implement the IDisposable interface, and you will have to define the public Dispose method as goverend by the interface. This method should look like this:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
This will call the protected Dispose(bool) method that takes care of the actual cleanup.
Also, include a vaiable in your class to indicate if the class is disposed or not:
private bool alreadyDisposed = false;
GC.SuppressFinalize tells the garbage collector that this item does not need to be finalized even if it has a finalizer.
Then you need the protected Dispose method. Make it protected instead of private in case any derived class needs to override it:
protected virtual void Dispose(bool isDisposing)
{
if (alreadyDisposed)
{
return;
}
if (isDisposing)
{
// free all managed resources here
}
// free all unmanaged resources here.
alreadyDisposed = true;
}
The finalizer should also call Dispose(bool) if the user forgets to clean up:
~SomeClass(){
Dispose(false);
}
If some method require a disposed resource to function, make the function like this:
public void SomeMethod()
{
if (alreadyDisposed)
throw new ObjectDisposedException("SomeClass",
"Called SomeMethod on Disposed object");
// Method body goes here
}
That's it. This will make sure that the resources gets cleaned up. Preferable by the user of your class calling Dispose, but by adding a Finalizer as a fallback method.
While you're learning about design patterns, you should also look at some common anti-patterns, you get an idea where the pattern comes from. IDisposable is somewhat of an anti-pattern, a minor version of sequential coupling, in that it requires a user to call dispose, and if he forgets, you're in the shit. One of the main reasons of the "disposable pattern" is to fix this issue.
A preferred technique (of mine anyway), wherever possible, is not to expose an IDisposable object to a user, but expose a single method (call it Using(...) for example), which takes a delegate which would execute the code normally contained in your using(...) { } block. This method can perform your construction, execute the delegate, then dispose the resources it consumed, and omits at least 3 problems with IDisposable: That of the user forgetting to call it, the user calling it more than once, and the user calling it too early - you don't need to bother with that boilerplate "disposable pattern" when there's no IDisposable exposed.
An example, lets say I have a File IO requirement where I need to open the same files regularly (and thus, I can't be waiting on the garbage collector to call Finalize in the event that a user forgets to call Dispose).
class MyFileStream {
FileStream fs;
private MyFileStream(string filename, FileMode mode) {
fs = new FileStream(filename, FileMode.Open);
}
private void Dispose() {
fs.Dispose();
}
public static void Using(string filename, FileMode mode, Action<MyFileStream> use) {
MyFileStream mfs = new MyFileStream(filename, mode);
use(mfs);
mfs.Dispose();
}
public void Read(...) { ... }
}
A caller can then say
var x = default(...);
MyFileStream.Using("filename.txt", FileMode.Open, (stream) => {
x = stream.Read(...);
});
Console.WriteLine(x);
Note that this is rather similar to the using() { } language syntax anyway, only this time you are forced to use it, and it imposes further restrictions. One cannot forget to clear up the resources this way.
Still, this pattern isn't always suitable because you sometimes need the resources to last longer than just a method call or so, but if you find the opportunity to use it, do so.
I've completely gone off topic anyway, so back to what you were asking.
Do not use ICloneable - it says nothing about how an object is being cloned (deep or shallow), if you require such thing, create your own IDeepCloneable or IShallowCloneable interfaces instead.
For IEnumerable<>, it's a rare event that you need to create your own, because there's a rather large collection of existing classes in the framework already, and you can usually get additional features much more simply by implementing extension methods (Such as those in LINQ, or your own, making use of the powerful yield keyword, which will create an IEnumerable<> for you in the background).
I wouldn't say there's any specific pattern for the rest, they're pretty self explanatory.
For example the IDIsposable pattern should only be followed if you have some unmanaged resources inside your class that you need to dispose, and not if all the objects you need to dispose implements IDisposable themselves.
I disagee with the above. I never recommend allowing the GC to do clean up and be implicit about object and resource disposal. It's kind of like waiting for the maid to come around and pick up your wet towels at a hotel; it will happen eventually, but the right thing to do is pick them up and hang them up yourself.
Deterministic disposal of objects and keeping scope of those resources as minimal as possible will make for the leanest and most efficient applications, not to mention that for developers reading the code, it is much more explicit to dispose of resources and reads better. Like a beginning and an end to a story that one can see all in one place. I instantiate the object as late as possible and dispose of it as soon as possible after use minimizing scope. Either explicitly calling .Dispose on the object or utilizing a Using block that calls the .Dispose method automatically are (2) good ways of cleaning up.
There are also a lot of other interfaces I routinely implement, but it's not all of them I am sure if the way I implement them is the preferred way of doing it, and I might find out later on that it causes a subtle bug that is hard to find, that would probably have been non-existant if I had followed the proper pattern in the first place.
The entire purpose of an Interface is to create a guidline for the methods, properties, events, etc. that a class is to implement, but not provide the details on how to do it. That is up to you. There is no "pattern" per se of how to implement specefic Interfaces. Don't get thrown off by the IDisposable Interface. Upon creating the Interface in VS.NET, the plumming code is created for you which is not typical for an Interface, and in reality could be completely changed to what you need.
I think where you might be getting confused is about Implementing Interfaces that are in the .NET Framework, but you need to look at the concept of an Interface and not just the ones available in the Framework. If you really want to see examples of how the Interfaces in the .NET Framework are implemented, look at either the MSDN or decompile other Framework objects that implement those Interfaces to see how Microsoft implements them.
As you grow in OOD, you will begin to see the power behind interfaces and begin to create them for your classes. For example lets say you have an interface named IMachine with a method called .StartEngine(). We just want the implementer of the Interface to define all of the details themself; there is no 'pattern' to follow and we the Interface designer don't need to know or care how it is implemented. For a car maybe the methods implementation involves "Get the keys, place them in the ignition, put in park, press brake pedal, turn ignition..." However for a lawnmower the same methods implementation is "Put gass in the mower, prime the carborateor, pull the clutch, pull the cord..."
So you see you can't just look at Interfaces by the ones in the .NET Framework and how to apply a certain pattern to thier implementation. The implementation details, patterns, etc. are up to the implementing class, and as long as the details of the Interface are sufficed, then thats what matters.
Hope this helps a bit...

Categories

Resources