Reducing interface with Disposable

1

I saw an example implementation of a interface with Disposable which I think is redundant and would like to know if I'm right.

Here is an example to illustrate:

public interface IClassBase<TEntity> where TEntity : class
{
        void Add(TEntity obj);
        void Dispose();
}

The inteface above brings the method Dispose as a contract

public class ClassBase<TEntity> : IDisposable, IClassBase<TEntity> where TEntity : class
{

    public void Add(TEntity obj)
    {
        throw new NotImplementedException();
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

So, IDisposable already forces me to implement the Dispose() method and it is unnecessary to add this method to my interface IClassBase , is this reasoning correct?

    
asked by anonymous 04.10.2016 / 04:14

2 answers

3

And who guarantees that you will use the IDisposable interface in the class that will also use IClassBase<TEntity> ? Having Dispose() in it is guaranteed that you will have to implement the method. If you do not have it, be an option. I'm actually being nice to talk about choice. Is it option how? Does the documentation say to do this? If it is, it does not guarantee anything, and I do not even know if it's the documentation function to do this. The fact is that without guarantees in statically typed language, it is a mistake not to have it.

Remember that the function of the interface is to be a contract, is to ask your implementers to require certain methods. So he must demand everyone. You can not expect a coincidence to do what you want. If you leave this method out of it you are saying that it does not matter. Furthermore, if access is done through the interface, you can not call Dispose() if it is not listed there. The type protects from access to other members. I've already replied in another question .

Not that it is forbidden, you have reasons to do this pragmatically speaking, but conceptually using an interface and saying that its method will not be implemented means that the interface should not be used. I know it can be implemented later, no problem, but it's good to make this alert to anyone who does not realize it.

    
04.10.2016 / 10:47
3

In your example, we recommend that your interface implement IDisposable:

public interface IClassBase<TEntity> : IDisposable where TEntity : class
{
    void Add(TEntity obj);
}

In this way you force classes to implement your interface, also implement IDisposable.

On the other hand, this may not make much sense, since IDisposable is usually implemented by classes that use native methods and need to release the resources used manually, which will not be freed by Garbage Collecor.

So what you need to know is: Does it make sense for you to create an interface that forces the implementation of Dispose?

I usually do not care about this, I leave it to anyone to implement my interface to decide whether or not I need IDisposable, and in that case, I implement IDisposable directly in the class. Remembering that it is recommended to implement Dispose in the set with the class finalizer . For the Garbage Collector does not call the Dispose, just the class finalizer.

Also remembering another very useful feature when a class implements IDisposable, is the possibility of using the object within a block using . Ensuring the correct use of IDisposable by calling Dispose automatically at the end even though an error occurs.

UPDATE : since the answer is not clear, so here goes:

No. It is not redundant. The method name is just a name. As I explained above, the IDisposable interface has these peculiarities, such as the possibility of using the using block. And as I said, the implementation of the interface is more a "hint" that the class uses native code that needs to release something manually.

You can have your own Dispose method and you can also implement the IDisposable.Dispose. Just implement the interface explicitly:

using System;

namespace ConsoleApplication1
{
    internal interface IMyDisposable
    {
        void Dispose();
    }

    internal class MyDisposable : IMyDisposable, IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("Dispose da interface IMyDisposable");
        }

        void IDisposable.Dispose()
        {
            Console.WriteLine("método implementando explicitamente Dispose da interface IDisposable");
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            using (var m = new MyDisposable())
            {
                m.Dispose();
            }

            //ou então:
            var m2 = new MyDisposable();
            m2.Dispose();
            ((IDisposable)m2).Dispose();

            /*
            print:
            Dispose da interface IMyDisposable
            método implementando explicitamente Dispose da interface IDisposable
             */
        }
    }
}
    
07.10.2016 / 15:43