Reputation: 10123
I'm having a bit of an issue casting my objects in C# to be able to use the additional object methods besides the ones declared in the interface. Below is a simple example of what I am speaking about.
public interface IShape
{
void Print();
}
public class Square : IShape
{
#region IShape Members
public void Print()
{
HttpContext.Current.Response.Write("Square Print Called");
}
#endregion
public void PrintMore()
{
HttpContext.Current.Response.Write("Square Print More Called");
}
}
Why when this code below is called am I not able to access PrintMore()?
IShape s = (Square)shape;
s.PrintMore() // This is not available. only Print() is.
Any help and explanation would be helpful?
Upvotes: 3
Views: 159
Reputation: 9983
Because when you try s.PrintMore()
"s" is of type IShape, so it only knows about the interface functions. You'd need to do something like
Square s = (Square)shape;
s.PrintMore();
or
((Square)shape).PrintMore(); // assuming you're positive its a Square type
Think of the interface like a wrapper over your object that only exposes only the functions defined in the interface. They're still there, you just can't access them without a cast to the appropriate object.
Upvotes: 1
Reputation: 6451
The reason you are unable to access the PrintMore
method is because you're reassigning the type-casted shape, back to a variable defined as IShape
. To be able to use methods on the Square
class you need to store it in a variable of type Square
for example:
Square s = (Square)shape;
s.PrintMore();
or alternatively:
((Square) shape).PrintMore();
Although it might be worth taking a good look at your code, type-casts such as these are usually a good warning sign that perhaps it is not ideal. Perhaps IShape
should have the PrintMore
method, or perhaps you should only be accepting Square
objects at this point? At the very least I'd suggest making sure that the shape
is actually of type Square
before doing this type cast.
For example:
Square s = shape as Square;
if (s != null)
s.PrintMore();
Upvotes: 1
Reputation: 4620
IShape s = (Square)shape;
s.PrintMore();
With this code s
is still an IShape
, not a Square
. A variable keeps the type you have defined at his declaration, whatever you try to fill in it.
To work the code should be :
Square s = (Square)shape;
s.PrintMore();
Upvotes: 2
Reputation: 1500225
Your s
variable is still of type IShape
. Just because you happen to have used a cast when assigning to it doesn't change the type as far as the compiler's concerned. You'd need:
Square s = (Square) shape;
s.PrintMore();
Of course, this will only work if shape
really is a Square
(assuming there aren't custom conversions going on).
I would advise you to think carefully before going down this route though. Usually a cast like this indicates that you're breaking abstraction somewhat - if you only know about shape
as an IShape
, you should (usually) be able to do what you need just with the members of IShape
. If that's not the case, you can:
IShape
more powerful (give it more members)Square
instead of an IShape
Upvotes: 5
Reputation: 38397
The problem is you are trying to access PrintMore()
off of an IShape
reference, IShape
references only see the Print()
method they declare.
So the cast you have (Square) shape
is doing nothing because it is immediately storing it into an IShape
reference. You need the reference itself to be Square
by either casting and storing it in a Square
reference, or by casting before the invoke:
Square s = (Square) shape;
s.PrintMore();
Or
IShape s = shape;
((Square)s).PrintMore();
Or, if you aren't sure if it's a Square
or not, use an as
cast:
Square s = shape as Square;
// will cast if it is a Square, otherwise, returns null
// this doesn't work for value types (int, struct, etc)
if (s != null)
{
s.PrintMore();
}
Upvotes: 4
Reputation: 27599
In the line IShape s = (Square)shape;
you are telling the compiler that s is an IShape so only methods on IShape are available.
If you user:
Square s = (Square)shape;
s.PrintMore()
Then that should do what you want.
The key point here is that when you declare a variable you tell the compiler what it is and it doesn't then matter what object you put into that.
Upvotes: 3