I like very much the hint: "Program against an interface, not an implementation" and I am trying to follow it consistently. However I am in doubt how to keep this principle working when I have to decouple my code from objects that must inherit from several interfaces. A typical example could be:
namespace ProgramAgainstInterfaces { interface IMean { void foo(); } class Meaning : IMean , IDisposable { public void Dispose() { Console .WriteLine("Disposing..." ); } public void foo() { Console .WriteLine("Doing something..." ); } } class DoingSomething { static void Main( string[] args) { IMean ThisMeaning = (IMean ) new Meaning (); // Here the issue: I am losing the IDisposable methods ThisMeaning.foo(); ThisMeaning.Dispose(); // Error: i cannot call this method losing functionality } } }
A possible way to solve this could be to define an ad-hoc interface that inherits from both the interfaces:
namespace ProgramAgainstInterfaces { interface IMean { void foo(); } interface ITry : IMean , IDisposable { } class Meaning : ITry { public void Dispose() { Console .WriteLine("Disposing..." ); } public void foo() { Console .WriteLine("Doing something..." ); } } class DoingSomething { static void Main( string[] args) { ITry ThisMeaning = (ITry ) new Meaning (); // This works ThisMeaning.foo(); ThisMeaning.Dispose(); // The method is available } } }
but i am not sure if this is the more compact and effective solution: I could have more complex multiple inheritance hierarchies and this add complexity because I must create interfaces only to act as containers. There is a better design solution?
If being an "IMean" object involves always being disposable, then you should make the interface implement it like :
public interface IMean : IDisposable { ... }
However, if it has sense to have an object implementing IMean without being disposable, then I think the solution you suggest is the best : create an intermediary interface so you may have :
public interface IMean { ... } public interface IDisposableMean : IMean, IDisposable { ... }
You should have the interface
implement IDisposable
not the class Meaning
. That way when casting to the interface
you don't lose that IDisposable
ability (because it's defined at your interface
level).
Like this:
namespace ProgramAgainstInterfaces { interface IMean : IDisposable { void foo(); } interface ITry : IMean { } class Meaning : ITry { public void Dispose() { Console .WriteLine("Disposing..." ); } public void foo() { Console .WriteLine("Doing something..." ); } } class DoingSomething { static void Main( string[] args) { ITry ThisMeaning = (ITry ) new Meaning (); // This works ThisMeaning.foo(); ThisMeaning.Dispose(); // The method is available } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With