Understanding Up-casting and Down-casting c#

2020-08-02 11:51发布

问题:

So I'm trying to understand up-casting and down-casting in c#.

My question is, is this diagram correct or am I still missing something? If its incorrect, where can I find a diagram that represents this concept correctly?

Any help is greatly appreciated.

Edit: Firstly I apologize for the confusion, I realize the diagram is not very clear and that I made a mistake in the down-casting one (where circle2 only has access to string Colour, it should have access to all the properties). I'll try and explain better what I was trying to represent.

So, here is the code that would go with it:

        public class Shape 
        {
           public int Width {get;set;}
           public int Height {get;set;}
           public int X {get;set;}
           public int Y {get;set;}
           public void Draw()
           {
             //do something
           }
        }

        public class Circle : Shape 
        {
           public string Colour {get;set;}
        }
        public class Program
        {
            public static void Main(string[] args)
            {
                //Up-casting
                Circle circle = new Circle(); //object is created
                Shape shape = circle; // shape point to circle object

                //Down-casting
                Circle circle2 = (Circle)shape;
            }
        }

回答1:

You don't need any diagrams, just get the basic facts down right and everything becomes crystal clear.

Up and down casting presupose an order, so lets get that straight first:

In a typical type hierarchy we have the following:

Animal -> Vertebrate -> Mammal -> Feline -> Cat

The higher, or more general, type is Animal and the lowest, or more specific, type is Cat; the order is therefore the "generalness" of the type.

Upcasting is casting to a more general type, and down casting is casting to a more specific type:

  • Up casting : Animal animal = new Cat();
  • Down casting: var feline = (Feline)animal;

Ok, but was is really going on in both "casts"? What changes are done to the objects when we down or up cast? The answer is rather simple; nothing! No changes whatsoever are done to the objects at all.

Both casts are reference conversions which are identity preserving; this means that the object before the cast and after the cast are(is) exactly the same object. As the name implies, the only thing you are changing is the type of the reference pointing to the object; the variables animal and cat.

This is made obvious by doing: ReferenceEquals(animal, feline); which will return true.

Note the upcasting is always implicit, because it is always safe; a Cat is always a Feline which is always a Mammal, etc. Downcasts on the other hand have to be explicit because they are not guaranteed to be safe:

Animal animal = new Dog();
Feline feline = animal; //unsafe, can not implicitly do the conversion

The compiler asks you to perform the cast explicitly, which is a way to tell the compiler "I know what I'm doing, animal is a Feline, trust me.". Of course the compiler will trust you only partially and will still provide runtime guards to make sure the cast is possible or throw a runtime exception if it isn't. In the code above, the cast will obviously fail and you will get a runtime error.

Do note that all this only applies to Reference Types. Value Types, by definition, don't have reference conversions because you can't get a reference to a value type. This is one of the reasons why type variance is not allowed in value types; there are no identity preserving conversions, the only conversions allowed in type variance.



标签: c# oop