Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Interface inheritance a bad practice?

I was wondering if the following code shows a bad practice (about interface inheritance):

public interface IFoo : IDisposable
{
    void Test();
}

public class TestImpl : IFoo
{
    public void Test()
    {
        // do something
    }

    public void Dispose()
    {
        // disposing my dependencies
    }
}

public class FooFactory
{
    public IFoo CreateFoo()
    {
        return new TestImpl();
    }
}

public class Client
{
    public void Main()
    {
        FooFactory factory = new FooFactory();
        using(IFoo foo = factory.CreateFoo())
        {
            // do stuff then auto-dispose
            foo.Test();
        }
    }
}

Here, I wanted two things: 1. Use the C#'s using statement so I can dispose my concrete object's dependencies elegantly (no need to cast anything to IDisposable). 2. Use a factory method to create a concrete object, so I can work only with the interfaces.

Separated, both are known good practices, but together? I didn't find anything saying it's wrong here http://msdn.microsoft.com/en-us/library/ms229022.aspx (MSDN - Interface Design), but I think it doesn't sound good...

I would appreciate any comment about this. If it's a bad practice, what kind of issues I would run into using this approach?

Thanks!

like image 825
Fabio Avatar asked Aug 09 '11 14:08

Fabio


People also ask

Which is better inheritance or interface?

We can inherit enormously more classes than Inheritance, if we use Interface. Methods can be defined inside the class in case of Inheritance. Methods cannot be defined inside the class in case of Interface (except by using static and default keywords). It overloads the system if we try to extend a lot of classes.

Why Multiple inheritance is not a good idea?

Allowing multiple inheritance makes the rules about function overloads and virtual dispatch decidedly more tricky, as well as the language implementation around object layouts. These impact language designers/implementors quite a bit and raise the already high bar to get a language done, stable, and adopted.

Can an interface be inherited?

Interfaces can inherit from one or more interfaces. The derived interface inherits the members from its base interfaces. A class that implements a derived interface must implement all members in the derived interface, including all members of the derived interface's base interfaces.

Are marker interfaces bad C#?

The design guidelines for interfaces specifically says: Avoid using marker interfaces (interfaces with no members). Custom attributes provide a way to mark a type. For more information about custom attributes, see Writing Custom Attributes.


2 Answers

In the wild, there is no such thing as a definitely good or bad practice, each has its upsides and downsides.
A practice becomes good or bad only when it is applied to a concrete problem (read: not IFoo).

public bool IsGood<TContext>(IPractice practice)
    where TContext : RealWorldApplication, new();

So, instead of trying to find guidance on MSDN, ask yourself the following question:

Does this solve the problem and make the code simpler to read?

If the answer is yes, go with it.

Personally, I like the approach. If the contract for IFoo requires proper disposal (think: IGraphicalObject, IResource, IConnection), it's a very good design decision to make this explicit.

Don't be trapped by dogma: programming with interfaces makes you less dependent on concrete implementations, but programming only with interfaces can be a nightmare. Be reasonable, that's it.

Update

You can use Google to find all interfaces that inherit from IDisposable in .NET Framework itself:

intitle:interface "inherits idisposable" site:msdn.microsoft.com

As I said above, this is normally done for entities that are known to consume resources, such as database connections, unmanaged object wrappers, graphical objects, et cetera.

Imposing implementing Dispose() on a class that has nothing to dispose of would be a bad idea.
In this case it's better to leave it optional and check for IDisposable support, as suggested by Peter.

like image 63
Dan Abramov Avatar answered Sep 22 '22 21:09

Dan Abramov


This is perfectly valid. That's exactly what interfaces are for. They define contracts. A contract can be built using several sub contracts.

like image 31
Daniel Hilgarth Avatar answered Sep 20 '22 21:09

Daniel Hilgarth