In the comments of this answer it is stated that "checking whether the object has implemented the interface , rampant as it may be, is a bad thing"
Below is what I believe is an example of this practice:
public interface IFoo { void Bar(); } public void DoSomething(IEnumerable<object> things) { foreach(var o in things) { if(o is IFoo) ((IFoo)o).Bar(); } }
With my curiosity piqued as someone who has used variations of this pattern before, I searched for a good example or explanation of why it is a bad thing and was unable to find one.
While it is very possible that I misunderstood the comment, can someone provide me with an example or link to better explain the comment?
To declare a class that implements an interface, you include an implements clause in the class declaration. Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class.
The java “instanceof” operator is used to test whether the object is an instance of the specified type (class or subclass or interface). It is also known as type comparison operator because it compares the instance with type. It returns either true or false.
If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface. By casting object1 to a Relatable type, it can invoke the isLargerThan method.
Implementing an interface means to actually write some code to fulfill the description of the interface, in terms of function names, attributes and return values.
It depends on what you're trying to do. Sometimes it can be appropriate - examples could include:
Count
which can be performed more efficiently on an IList<T>
via the specialized members.In other cases it's less appropriate and you should consider whether you can change the parameter type instead. It's definitely a "smell" - normally you shouldn't concern yourself with the implementation details of whatever has been handed to you; you should just use the API provided by the declared parameter type. This is also known as a violation of the Liskov Substitution Principle.
Whatever the dogmatic developers around may say, there are times when you simply do want to check an object's execution time type. It's hard to override object.Equals(object)
correctly without using is
/as
/GetType
, for example :) It's not always a bad thing, but it should always make you consider whether there's a better approach. Use sparingly, only where it's genuinely the most appropriate design.
I would personally rather write the code you've shown like this, mind you:
public void DoSomething(IEnumerable<object> things) { foreach(var foo in things.OfType<IFoo>()) { foo.Bar(); } }
It accomplishes the same thing, but in a neater way :)
I would expect the method to look like this, it seems much safer:
public void DoSomething(IEnumerable<IFoo> things) { foreach(var o in things) { o.Bar(); } }
To read about the referred violation of the Liskov Principle: What is the Liskov Substitution Principle?
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