Frage

What is the difference between cast object to interface cast object to class like this example.

namespace ConsoleApplication1
{
    interface IAnimal
    {
        string Sound();
    }

    class Animal : IAnimal
    {
        public string Sound()
        {
            return "Animal sound";
        }
    }

    class Lion : Animal, IAnimal
    {
        public string Sound()
        {
            return "Roarrrrr";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Lion lion = new Lion();
            IAnimal animal = (Animal)lion; // variant 1

            IAnimal animal2 = (IAnimal)lion; // variant 2

            Console.WriteLine(animal.Sound());
        }
    }
}

What is the difference between variant 1 and variant 2 ?

War es hilfreich?

Lösung

The only difference is in how the compiler checks that the casts are allowed.

In the first variant the compiler checks how Lion can be cast to Animal, then it checks how Animal can be cast to IAnimal. As both cast can be done safely as Lion is an Animal and Animal is an IAnimal, the compiler generates no code for casting at all, it's just an assignment.

In the second variant the compiler checks how Lion can be cast to IAnimal, then it checks if IAnimal is the same as IAnimal. As the cast can be done safely it generates no code for casting there either, it's also just an assignment.

As Lion is an IAnimal you don't need to do any casting at all, you can just assign it to the variable:

IAnimal animal3 = lion;

In that case the compiler will check how Lion can be cast to IAnimal, and as that can be done safely it doesn't generate any code for casting, just the assignment.

Andere Tipps

In

IAnimal animal = (Animal)lion;

there's an implicit conversion going on because animal is declared as IAnimal, and Animal is convertible to IAnimal (because the class implements the interface).

It corresponds to writing

Lion lion = new Lion();
Animal a = lion;
IAnimal ia = a;

All these conversions are possible.

However, you could also just have written:

IAnimal lion = new Lion();

On the other hand, if you had written

var animal = (Animal)lion;

animal would have been an instance of Animal.

Literally there is no difference in compiled IL. but there exist an implicit conversion which is performed by compiler when you assign Animal to IAnimal. Compiler is happy in doing that because it knows Animal implements IAnimal.

Here's the IL which shows what I mean.

IL_0001:  newobj      UserQuery+Lion..ctor //Create new lion
IL_0006:  stloc.0     // store it in variable lion
IL_0007:  ldloc.0     // load variable lion
IL_0008:  stloc.1     // store it in variable animal
IL_0009:  ldloc.0     // load variable lion
IL_000A:  stloc.2     // store it in variable animal2
IL_000B:  ldloc.1     // load variable animal
IL_000C:  callvirt    UserQuery+IAnimal.Sound //Call animal.Sound 
IL_0011:  call        System.Console.WriteLine //With the result call Console.WriteLine

In your first example you are performing a explicit conversion to Animal and then an implicit conversion is taking place to convert it to IAnimal similar to IAnimal animal = (IAnimal)(Animal)lion;. The second example is simply performing an implicit conversion and, for all intents and purposes, you can remove the cast in the second example.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top