Click here to Skip to main content
15,908,111 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
My code:
C#
class MyBaseClass 
{ 
    public void Print() 
    { 
        Console.WriteLine("This is the base class."); 
    } 
} 
    
class MyDerivedClass : MyBaseClass 
{ 
    new public void Print() 
    { 
        Console.WriteLine("This is the derived class."); 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
        MyDerivedClass derived = new MyDerivedClass(); 
        MyBaseClass mybc = (MyBaseClass)derived; 
    
        derived.Print(); // Call Print from derived portion. 
        mybc.Print(); // Call Print from base portion. 
    } 
} 

If I change the line:
C#
MyBaseClass mybc = (MyBaseClass)derived;
to
C#
MyBaseClass mybc = new MyBaseClass();
, the result was the same to.

My question: Can you tell me what is the difference?

Thanks!
Posted
Updated 14-Oct-14 19:24pm
v3
Comments
Sergey Alexandrovich Kryukov 15-Oct-14 1:26am    
You need to understand runtime classes vs compile-time classes.
—SA

Please see my comment to the quesiton.

There is no difference. You can always assign an instance of the derived class to a variable/member of a base class. Isn't it obvious?
Because the instance of some class is always also an instance of the base class.

Your example does not illustrate anything. But let's assume that derived class adds some new member with different name, for simplicity:
C#
class A {
   internal void First() {/* ... */}
}
class B : A {
   internal void Second() {/* ... */}
}

Why the code below will always work?
C#
B b = new B();
// or even A b = new B();
A a = b;
a.First();

This is because the method First will always present in object of the type A, even if the runtime type is actually B, because B is also A; First is inherited.

The opposite case would mean the attempt to use non-existing method Second:
C#
A a = new A();
B b = (B)a; // this cast is possible,
            // but only if runtime type of b is B
            // or derived from B
// otherwise the cast exception will be thrown

Why cast exception? Because otherwise it would make the call b.Second() possible, but this method does not actually exist in the runtime type.

Your original code sample illustrates the member hiding, which only clouds understanding of more fundamental thing. Understand it first, and then try to analyze hiding.

—SA
 
Share this answer
 
v3
Comments
Maciej Los 15-Oct-14 1:57am    
Agree, +5!
And it's worth to notice that Print method of B class is using new keyword, which means...
Versioning with the Override and New Keywords (C# Programming Guide)[^]
Sergey Alexandrovich Kryukov 15-Oct-14 3:10am    
Thank you, Maciej.
—SA
[no name] 15-Oct-14 16:49pm    
// this cast is possible, but only if runtime type is B or derived from B ?
Sergey Alexandrovich Kryukov 15-Oct-14 17:26pm    
Thank you very much for pointing out my mistake. Fixed:
// but only if runtime type of b is B
// or derived from B

—SA
An instance of a derived class cast to its base class will, of course, invoke a method declared using the 'new keyword with the same name and signature (parameter Type list) defined in the base class. There is a difference in structure, yes, but not a difference in behavior.

A derived class cast to its base class is-a base class; and it no longer has access to fields, properties, and methods defined in the derived class.

It may help you to think of a stack of dictionaries: in this case the derived class by use of the keyword 'new before the definition of the 'Print method defines a dictionary entry in the dictionary which is "on top:" it hides the definition of 'Print in the base class dictionary.

When you cast an instance of the derived type to the base class, then, essentially you are moving the base-class dictionary to the top, you hide the derived class dictionary, and so, the compiler locates the method bound to the method-name 'Print to execute in the base class dictionary.

Note that you can still execute the method defined in the base class by calling it from within the derived class:
C#
class MyDerivedClass : MyBaseClass
{
    new public void Print()
    {
        Console.WriteLine("This is the derived class.");

        // call the base class method
        base.Print();
    }
}
If you want to make a class where you will always use the derived class definition of 'Print:
C#
abstract class MyVirtualBaseClass
{
    public virtual void Print()
    {
        Console.WriteLine("This is the base class.");
    }
}

class MyDerivedClass2 : MyVirtualBaseClass
{
    public override void Print()
    {
        Console.WriteLine("This is the derived2 class."); 
    }
}

// test
MyDerivedClass2 derived2 = new MyDerivedClass2();
MyVirtualBaseClass mybc2 = (MyVirtualBaseClass)derived2;

derived2.Print();
mybc2.Print();
Now you will see that even though the derived class was cast to its base type only the 'Print method in the derived class was called.

It takes some time to get used to these concepts, which are essential to the C# language design.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 15-Oct-14 3:12am    
5ed.
I would add that this is not about specifically C# design, but .NET and CLI design, and big par of it — general OOP.
—SA
Maciej Los 15-Oct-14 3:29am    
+5!
Once write this code and execute you can find the difference

    class MyBaseClass
    {
        public void Print()
        {
            Console.WriteLine("This is the base class.");
        }
        public virtual void add()
        {
            Console.WriteLine("add calc : base class");
        }
    }

    class MyDerivedClass : MyBaseClass
    {
        new public void Print()
        {
            Console.WriteLine("This is the derived class.");
        }

        public override void add()
        {
            Console.WriteLine("add calc : dervied class");
        }
    }


class Class8
    {
        static void Main()
        {
            MyDerivedClass derived = new MyDerivedClass();
            MyBaseClass mybc = derived; //casting is not requeired

            derived.Print(); // Call Print from derived portion. 
            mybc.Print(); // Call Print from base portion. 

            derived.add(); // Call add from derived portion. 
            mybc.add(); // Call add from derived portion. because, override method of base class in derived class.
        }
    }
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 15-Oct-14 1:29am    
Not only this code dump does not explain anything, it does not even illustrate anything. I really doubt you understand the problem yourself (please forgive me if I'm wrong here).
—SA
Samatha Reddy G 15-Oct-14 2:06am    
i understood the problem but am unable to express that's i gave a code, if we execute it then we can come to know the difference

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900