Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface inheritance with IDisposable?

Tags:

c#

inheritance

I have the following inheritance hierarchy:

public interface IRepository<T> : IDisposable
{
    void Add(T model);
    void Update(T model);

    int GetCount();

    T GetById(int id);
    ICollection<T> GetAll();
}

public interface IAddressRepository : IRepository<Address>
{
}

And this code:

var adrs = new Address[]{
    new Address{Name="Office"}
};

using (IAddressRepository adrr = new AddressRepository())
    foreach (var a in adrs)
        adrr.Add(a);

However, this code does not compile. It gives me this error message:

Error   43  
'Interfaces.IAddressRepository': type used in a using statement must be
 implicitly convertible to 'System.IDisposable'

However, a parent of IAddressRepository inherits from IDisposable.

What is happening here? How do I make the code compile?

like image 238
Oliver Avatar asked May 22 '12 15:05

Oliver


People also ask

Can an interface inherit IDisposable?

Concrete types can implement IDisposable, but interfaces should not, since IDisposable is an implementation detail.

What is the IDisposable interface?

IDisposable is an interface defined in the System namespace. It is used to release managed and unmanaged resources. Implementing IDisposable interface compels us to implement 2 methods and 1 boolean variable – Public Dispose() : This method will be called by the consumer of the object when resources are to be released.

How is IDisposable interface implemented?

For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.

Why IDisposable interface is used?

Typically, types that use unmanaged resources implement the IDisposable or IAsyncDisposable interface to allow the unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you call the object's Dispose or DisposeAsync implementation to explicitly perform cleanup.


2 Answers

Works for me:

using System;

public class Address {}

public interface IRepository<T> : IDisposable
{
    void Add(T model);
    void Update(T model);
}

public interface IAddressRepository : IRepository<Address>
{
}

class Program
{
    public static void Main()
    {
        using (var repo = GetRepository())
        {
        }
    }

    private static IAddressRepository GetRepository()
    {
        // TODO: Implement :)
        return null;
    }
}

I suspect you may have two IAddressRepository interfaces. Are you sure it's Interfaces.IAddressRepository that extends IRepository<T>, and that that extends IDisposable?

like image 41
Jon Skeet Avatar answered Nov 03 '22 00:11

Jon Skeet


My guess is that you are making a mistake- either you have not recompiled the assembly containing the IRepository<T> interface since you made it inherit from IDisposable, or you are referencing the wrong copy of it, or you are referencing some other IAddressRepository.

Try doing a Clean, then a Rebuild All, and check the paths on your references. If the projects are in the same solution, make sure you are referencing the project containing IRepository<T> / IAddressRepository and not the DLL.

Also make sure that AddressRepository actually implements IAddressRepository. It might just be reporting the wrong error.

EDIT: So the resolution seems to be that the assembly containing AddressRepository's parent class was not compiling. This caused the debugger to complain about AddressRepository not implementing IDisposable, rather than the (more sensible) " inaccessible due to its protection level" error compiling the class itself. My guess is you had that error too, but were addressing this one first.

like image 144
Chris Shain Avatar answered Nov 03 '22 01:11

Chris Shain