基本引用类型与派生引用类型之间有什么区别 [英] What is the difference between base reference type vs derived reference type

查看:96
本文介绍了基本引用类型与派生引用类型之间有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Dog
{
}
class BullDog : Dog
{
}
class Program
{
    static void Main()
    {
        Dog dog2 = new BullDog();
        BullDog dog3 = new BullDog();
    }
}




  1. 什么Dog作为参考与BullDog作为参考有什么区别?

  1. What is the difference between using Dog as a reference vs BullDog as a reference?

我习惯于使用 var dog3 = new BullDog (); ,类似于 BullDog dog2 = new BullDog(); 。什么时候需要使用 Dog dog2 = new BullDog();

I have an habit of using var dog3 = new BullDog();, which is similar to BullDog dog2 = new BullDog();. When do we need to use Dog dog2 = new BullDog();?


推荐答案

编辑:要从评论中解决其他问题:

To address the additional question from the comments:

static void TakesDog(Dog theDog) { ... }

static void TakesBulldog(Bulldog theBulldog) { ... }

static void TakesObject(object theObject) { ... }

static void Main()
{
    //Given these declarations...
    object dog = new BullDog();
    Dog dog2 = new BullDog();
    BullDog dog3 = new BullDog();

    //These calls will work because a BullDog is a Dog:
    TakesDog(dog2);
    TakesDog(dog3);

    //this call will work because a Bulldog is a Bulldog:
    TakesBulldog(dog3);

    //and these calls will ALL work because all Dogs are Objects:
    TakesObject(dog);
    TakesObject(dog2);
    TakesObject(dog3);

    //However, these calls will fail because an Object or Dog is not 
    //necessarily a Bulldog,
    //EVEN THOUGH our current dog and dog2 are indeed references to Bulldogs:
    TakesBulldog(dog);        
    TakesBulldog(dog2);

    //An explicit conversion is necessary to make the above calls work:
    TakesBulldog(dog2 as Bulldog); //works given the current reference
    TakesBulldog((Bulldog)dog2); //works given the current reference
    TakesBulldog(dog as Bulldog); //ditto
    TakesBulldog((Bulldog)dog); //ditto

    //but if we change the value of dog2 to some other dog:
    dog2 = new Labrador();

    //the above calls now fail:
    TakesBulldog(dog2 as Bulldog); //passes null into the method
    TakesBulldog((Bulldog)dog2); //throws InvalidCastException

    //you can avoid problems by checking the true type:
    if(dog2 is Bulldog) //interrogates the type of the referenced object
       TakesBulldog((Bulldog)dog2); //works
    else
       TakesDog(dog2); //general fallback case

    //Object is similar but even more basic:
    dog = "I'm a dog"; //now dog is a System.String

    //this call still works:
    TakesObject(dog);

    //but these will fail:
    TakesDog(dog);
    TakesBulldog(dog);
}

需要了解的最后一件事:

One last thing to understand:

//given these declarations:
object dog = new BullDog();
BullDog dog2 = new BullDog();

//even though dog is a BullDog, attempting to call BullDog-specific 
//members (methods, properties, fields) will fail:
dog.Drool();

//you may only call members as specific as the object type of the 
//variable holding the reference:
dog.ToString(); //defined by Object. If you've overridden it in Dog or BullDog,
   //you'll get that implementation
dog2.Drool(); //works because we know from the variable that dog2 is a BullDog.

这篇关于基本引用类型与派生引用类型之间有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆