A method should return the most specific type?

C

csharper

I have been reading here:

http://forums.asp.net/t/1423519.aspx

The quote of the last but one post says:

"NOTE This action method specifically declares that it returns an
instance of ViewResult. It would work just the same if instead the
method return type was ActionResult (the base class for all action
results). In fact, some ASP.NET MVC programmers declare all their
action methods as returning a nonspecific ActionResult, even if they
know for sure that it will always return one particular subclass.
However, it's a well-established principle in object-oriented
programming that methods should return the most specific type they can
(as well as accepting the most general parameter types they can).
Following this principle maximizes convenience and flexibility for
code that calls your method, such as your unit tests."

I haven't seriously thought about this, yes, it seems to be the case,
since our methods don't always return object. But what's the
rationale of polymorphism? I think polymorphism promotes the use of
more generic types, so, for example, with polymorphism, we do
something like:

Animal dog = new Dog();

assuming that Dog inherits Animal.

A little confused about "returning the most specific type" and
polymorphism.
 
C

csharper

csharper said:
[...]
However, it's a well-established principle in object-oriented
programming that methods should return the most specific type they can
(as well as accepting the most general parameter types they can).
Following this principle maximizes convenience and flexibility for
code that calls your method, such as your unit tests."
I haven't seriously thought about this, yes, it seems to be the case,
since our methods don't always return object.  But what's the
rationale of polymorphism? I think polymorphism promotes the use of
more generic types, so, for example, with polymorphism, we do
something like:
Animal dog = new Dog();
assuming that Dog inherits Animal.
A little confused about "returning the most specific type" and
polymorphism.

I don't see the rules of thumb in conflict.  Even in your example, the
type being returned is the most specific possible ("Dog") even though
it's being assigned to something less specific.

I think the advice could be stated in a slightly different way:
consumers should use the least-derived type they can, producers should
expose the most-derived type they can.

In many polymorphic scenarios, the most-derived type that is usable is
in fact a base class or interface.  The actual implementing type is
private, such as either as a nested class, internal to an assembly.

But, where there's an implementing type that's publicly available (for
example, the sub-classes of System.IO.Stream), the producer of the
instance should share that knowledge.  That way, if the client code has
a need to treat the instance as the more-derived type, it's trivial to
do so.

At the same time, the client code (the "consumer") should often _not_
actually use the more-derived type.  This helps document within the code
what the intended usage is, minimizing extraneous dependencies and the
temptation to complicate the usage of the instance.  The latter is
especially helpful if and when the code needs to be refactored for
reuse.  It helps ensure that general-purpose code really remains
general-purpose, even if in the original implementation the code is used
just in one place.

Pete

Thanks for the clarification. To understand it thoroughly, let me
reproduce part of the Steve Sanderson's quote:

"Following this principle maximizes convenience and flexibility for
code that calls your method, such as your unit tests."

So, according to the methods-should-return-most-specific-type
principle and the consumers-should-assign-to-least-derived-type
principle, by "convenience and flexibility", Steven Sanderson probably
means that consumers of such methods have more freedom in choosing
what type to assign the returned object to. So, for example, if I have
this inheritance chain:

Animal -> Mammal -> Canine -> Dog

and if MyMethod returns Dog, the consumer method has the freedom to do
this:

Dog myDog = MyMethod();
Canine myDog = MyMethod();
Mammal myDog = MyMethod();
Animal myDog = MyMethod();

In contrast, if MyMethod returns Animal, the consumer method will have
to cast down the type.

Does this sound like a good understanding?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top