Cast接口和类对象

时间:2014-05-11 08:31:38

标签: c# .net oop inheritance

如此示例所示,将对象转换为接口转换对象与类之间有什么区别。

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());
        }
    }
}

变体1和变体2之间有什么区别?

4 个答案:

答案 0 :(得分:3)

IAnimal animal = (Animal)lion;

隐式转化,因为animal被声明为IAnimalAnimal可转换为IAnimal(因为该类实现了界面)。

它对应于写作

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

所有这些转换都是可能的。

但是,你也可以写一下:

IAnimal lion = new Lion();

另一方面,如果你写过

var animal = (Animal)lion;

animal将是Animal的实例。

答案 1 :(得分:3)

唯一的区别在于编译器如何检查是否允许强制转换。

在第一个版本中,编译器会检查Lion如何转换为Animal,然后检查Animal如何转换为IAnimal。由于LionAnimalAnimalIAnimal,因此编译器可以安全地完成,编译器根本不会生成任何代码,它只是一个赋值。 / p>

在第二个版本中,编译器会检查Lion如何转换为IAnimal,然后检查IAnimal是否与IAnimal相同。由于演员阵容可以安全地完成,因此也不会在那里生成任何代码,它也只是一项任务。

由于LionIAnimal,您根本不需要进行任何投射,只需将其分配给变量:

IAnimal animal3 = lion;

在这种情况下,编译器将检查如何将Lion强制转换为IAnimal,并且因为这可以安全地完成,所以它不会生成任何用于转换的代码,只是生成赋值。

答案 2 :(得分:3)

在编译的IL中,字面意思是没有区别。但是当您将Animal分配给IAnimal时,存在一个由编译器执行的隐式转换。编译器很乐意这样做,因为它知道Animal实现了IAnimal

这是显示我的意思的IL。

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

答案 3 :(得分:1)

在您的第一个示例中,您正在执行向Animal的显式转换,然后进行隐式转换以将其转换为IAnimal,类似于IAnimal animal = (IAnimal)(Animal)lion;。第二个例子只是执行隐式转换,并且,对于所有意图和目的,您可以在第二个示例中删除强制转换。