views:

265

answers:

5

I see many methods that specify an interface as return value. Is my thought true that it means: my method can return every class type that inherits from that interface? if not please give me a good answer.

+11  A: 

Yes, your method could return any type that implements that interface.

Here is an example:

using System;

class Foo
{
    public IComparable GetComparable()
    {
        // Either of these return statements
        // would be valid since both System.Int32
        return 4;
        // and System.String
        return "4";
        // implement System.IComparable
    }
}
Andrew Hare
I'd add that it's almost always a bad idea to try to sniff out the actual type and downcast.
Steven Sudit
@Steven - It is usually a bad idea yes, but there are cases when downcasting can be very beneficial.
Andrew Hare
Nice example :)
Brian Rasmussen
@Andrew: Or even necessary. One such case involves IAsyncResult needing to be downcast to AsyncResult. http://stackoverflow.com/questions/1110066/winforms-ui-responsiveness-when-dealing-with-heavy-data
Steven Sudit
+2  A: 

Yes that is true

JonoW
+3  A: 

Yes, that method might return an object of any type that implements that interface.

But, to use the non-interface members of a particular type, you'll need to cast it to that type.

Patrick Karcher
Yeah, I tried to fix that right away, but someone else was editing my post too. Got all messed up. But I got my clean-up badge. :)
Patrick Karcher
+5  A: 

Yes, it means that the only thing you know about the object that is returned is that it implements the interface.

In fact, the actual type of the object may not even be accessible to the calling code. It could be a private type in a separate assembly.

And in fact, the method may return a different type from one invocation to the next (as in the case of an abstract factory).

Jeffrey L Whitledge
A competing answer, but I feel compelled to upvote! Your extra information bits would be very helpful to someone trying to understand this.
Patrick Karcher
@Patrick Karcher - Thanks! :-)
Jeffrey L Whitledge
+3  A: 

C++ supports a programming technique called polymorphism. That is a derived class can look like a base class to other code that knows nothing about the derived classes. Take a look at his example:

class Shape
{
public:
    virtual float Area () const = 0;
};

class Rectangle: public Shape
{
public:
    Rectangle (float width, float height)
        : m_width(width)
        , m_height(height)
    {}

    virtual float Area () const
    {
        return m_width * m_height;
    }

private:
    float m_width;
    float m_height;
};

class Circle: public Shape
{
public:
    Circle (float radius)
        : m_radius(radius)
    {}

    virtual float Area () const
    {
        return 3.141592653f*(m_radius*m_radius);
    }

private:
    float m_radius;
};

Now you can see from this code we've created a base class Shape (our interface) and two derived classes that specialise this class, one a rectangle, another a circle. Now let's create a function that prints out the area of a shape:

void PrintArea (const Shape& shape)
{
    printf("Area of shape = %f",shape.Area());
}

This function doesn't care if its a circle of rectangle. Or it cares about is that it's passed a shape and that you can get the area of it, regardless of type.

So this code uses this function:

 Rectangle r (5.0f,4.0f);
 Circle c (25.0f);

 PrintArea(r);      // Print the area of the rectangle
 PrintArea(c);      // Print the area of the circle

Hope this helps.

Cthutu
Oops I apologise I wrote this in C++, didn't read the question well enough to see you meant C#. But the same process applies. Let me know if you want me to rewrite the sample code above in C#.
Cthutu
thanks Cthutu. No this sample is very clear.
masoud ramezani