What is the difference between base reference type vs derived reference type

后端 未结 6 811
清酒与你
清酒与你 2021-01-07 13:20
class Dog
{
}
class BullDog : Dog
{
}
class Program
{
    static void Main()
    {
        Dog dog2 = new BullDog();
        BullDog dog3 = new BullDog();
    }
}
         


        
6条回答
  •  刺人心
    刺人心 (楼主)
    2021-01-07 14:08

    EDIT: 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.
    

提交回复
热议问题