Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing IDisposable with empty Dispose for reasons of readability

I like the using(){} statement for its control of scope and for readability. Not only can you create objects, use them and dispose them neatly, but you can also use it like this:

Suppose myInstance is an instance of MyClass from some other place in code - ie a method parameter or something

using (var t = myInstance) {
    t.Foo= "Hello";
    t.Bar= "World";
    ...
}

Definition of MyClass:

public class MyClass : IDisposable
{
   public string Foo {get; set;}
   public string Bar {get; set;}
   ...

   public void Dispose() {}
}

This makes code neater and more readable (I feel) and certainly easier to type. However in order to use this widely you have to implement IDisposable. In this case there's no need for MyClass actually handle anything in Dispose, so its empty.

My question is, is there any drawback to using IDisposable in this way?

I appreciate that there are similar questions already on SO, but I don't think these deal with using IDispose for this purpose (or they refer to specific classes).

EDIT:

OK, so I guess I was being a bit specifc, but there's a wider point here. The using statement is a handy, very neat way to define an instance for a specific length of time, and then you can forget about it. Its seems unfair that this ability should be restricted to IDisposable objects only. Yes there's a certain amount of laziness in not just instancing and then setting to null, but the using block makes it very specific what the instance's scope is. Why shouldn't I be allowed to do it with non IDisposable classes?

like image 641
Jon Egerton Avatar asked Mar 10 '11 13:03

Jon Egerton


People also ask

Which of these are the reason for implementing IDisposable interface?

If your class creates unmanaged resources, then you can implement IDisposable so that these resources will be cleaned up properly when the object is disposed of. You override Dispose and release them there.

What happens if you dont Dispose IDisposable?

IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.

When should we implement IDisposable interface?

You should implement IDisposable when your class holds resources that you want to release when you are finished using them. Show activity on this post. When your class contains unmanaged objects, resources, opened files or database objects, you need to implement IDisposable .

What is IDisposable interface in C implement the Dispose method?

IDisposable is an interface that contains only a single method i.e. Dispose(), for releasing unmanaged resources. IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources.


5 Answers

If your class doesn't need to be disposed, there's no point in using using.

Instead, you can make a normal block:

{ var t = myInstance;
    t.Foo= "Hello";
    t.Bar= "World";
    ...
}

However, I fail to see the purpose.

From a design perspective, you should not implement IDisposable unnecessarily.
Implementing IDisposable tells people who use your class that it uses expensive resources and must be disposed when finished with.
If that's not actually true, you're just making their job harder.

like image 79
SLaks Avatar answered Oct 06 '22 03:10

SLaks


Yes, the using block is syntactic sugar for a try/finally block.

like image 24
CheeZe5 Avatar answered Oct 06 '22 04:10

CheeZe5


I wouldn't (ab)use using just to limit the scope of variables within a method unless these types really need to be disposed - it may just confuse people. In the case of your example it sounds more like you want to add an additional method to structure your code better (and probably get the same readability benefit) :

public void WorkWithMyInstance(MyInstance t)
{
  t.Foo= "Hello";
  t.Bar= "World";
  ...
}
like image 37
BrokenGlass Avatar answered Oct 06 '22 03:10

BrokenGlass


When you implement IDisposable you're advertising that your class is special and needs to be disposed off properly. Not only with inline code like that but also when classes hold references to your class. They'll also need to implement IDisposable in order to dispose of your instance. That creates an artificial requirement on the users of your class.

You can use a scope to achieve what you want:

{
  var _ = instance;
  _.Foo = "Hello"; 
  _.Bar = "World"; 
}

Another option is this:

instance.With(_ => {
  _.Foo = "Hello";
  _.Bar = "World"; 
});

...

public static class WithExtensions {
  public static void With<T>(this T instance, Action<T> action) {
    action(instance);
  }
}

This one is better because what's going on is more explicit.

I also see the pain that you have. It'd be better if we could define our own control blocks (like in Nemerle). Although C# doesn't allow that kind of customization, you shouldn't abuse the specific using statement to achieve what you want. You can use lambdas to do that, much in the way I've shown with the With extension method. In fact, that's how some parallel "constructs" were done in the Task Parallel Library.

like image 22
Jordão Avatar answered Oct 06 '22 03:10

Jordão


You're not really using the interface as it was intended. Per the documentation:

The primary use of this interface is to release unmanaged resources.

If you're just using IDisposable so you can wrap it in a using statement, I think that gives the wrong impression to users of your classes. They may interpret this code as doing much more than what it really is doing.

I think the unintended consequence will be confusion.

like image 35
David Hoerster Avatar answered Oct 06 '22 04:10

David Hoerster