user9623401
user9623401

Reputation:

casting a type to another type in C#

I'm a beginner in OOP, just have a question on casting, let's say we have:

interface Animal
{
   string speak();
}

class Dog : Animal
{
   public string speak()
   {
       return "wan-wan";
   }
}

class Cat : Animal
{
   public string speak()
   {
     return "miao";
   }

   public void catchMouseS()
   {
      ...
   }
}

class Program
{
   static void Main(string[] args)
   {
     Animal generic= new Dog();
     Cat cutie = (Cat)generic;   
    }
}

so you can see that I can type a dog to a cat, the compiler is OK with that, shouldn't the compiler be smart enough to throw an error, because it will encounter error on run time for sure when the 'cutie' calls the catchMouses method since cutie is actually a dog which doesn't have catchMouses method?

Upvotes: 2

Views: 84

Answers (2)

TheGeneral
TheGeneral

Reputation: 81583

This is just the way polymorphism and interfaces work in .Net.

The compiler can statically analyse the Type of the Reference, but it doesn't dig into the run-time Type of the object in memory. It knows enough to know those 2 types implement the same contract and can make an Explicit Conversion, and it's good with that for good reasons.

Now, to you and me it's obvious Dog is not a Cat, we can see it in a handful of code, but the compiler doesn't try and figure out that type of problem at compile time. You could imagine if you had a million lines of code it would have to check billions (if not trillions) of path-ways to work-out if what you are doing is correct... All it knows at compile time is the Type at casting is valid (not what you try to do with it), and a conversion is possible.

So, to save time on what is really an enormous problem with lots of degrees of freedom, (the compiler) does a basic Static Check to see if there is a possible conversion, and allows you to make a mess of it, however it still does the run-time check.

Here is another way to hoodwink the compiler

class Dog
{
}

class Cat
{
}

public static void Main()
{
    Dog d = new Dog();
    var a = (object)d;
    Cat cutie = (Cat)a;
}

Both are reference types, both can be converted to object, and both conversion are seemingly possible, so it thinks you know what you are doing at compile time, obviously though the run-time checks fail.

Upvotes: 0

battlmonstr
battlmonstr

Reputation: 6300

The case you described is called downcasting and is considered a bad code for the exact reason you have mentioned. It is allowed at compile time, and crashes (or misbehaves) in runtime (or not).

You could also catch InvalidCastException and do something with it.

Upvotes: 0

Related Questions