Brandon
Brandon

Reputation: 10953

C# - Call Method in Base Class

I have 2 classes:

public class A
{
    public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

In my code I do the following:

B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'

I presumed this would work because of polymorphism.

However, it always writes 'Output from B' every time. Is there anyway to get this to work the way I want it to?

EDIT Fixing code example.

Upvotes: 3

Views: 3751

Answers (6)

TrueWill
TrueWill

Reputation: 25573

Your method on class A is Write, not WriteLine. Change it to the same name and it will work as you expect. I just tried it and get:

Output from B
Output

Polymorphism (C# Programming Guide) explains this quite well. (This is the newer version of the original poster's link.) The page shows examples where a derived class overrides a virtual member and where new members hide base class members.

There appears to be some confusion over the new modifier. From the documentation:

Although you can hide members without the use of the new modifier, the result is a warning. If you use new to explicitly hide a member, it suppresses this warning and documents the fact that the derived version is intended as a replacement.

Note that the hidden member does not need to be virtual.

Best practices:

  • Strongly prefer overriding to hiding. Polymorphic calls are idiomatic in OO languages.
  • If you intend to hide a member, always use the new modifier.
  • Never release code with compiler warnings.
  • If every developer on your team agrees that a compiler warning cannot be fixed, suppress it.

Upvotes: 1

Random Dev
Random Dev

Reputation: 52300

First: I guess you wanted to name the methods both "WriteLine" but the one in class A is only named "Write". And second: yes you inherit B from A but the object will still be of type "B" so now I don't think what you want is possible.

Upvotes: 0

Aleks
Aleks

Reputation: 1201

Your class A has a Write function instead of WriteLine

public class A
{
    public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

Upvotes: 0

Russ Clarke
Russ Clarke

Reputation: 17919

The 'new' keyword is making B's implementation of WriteLine overwrite A's implementation.

Don't accept this as an answer, but in my experience, it's almost always a mistake to use the 'new' keyword in this fashion. It's less readable and muddy's the clarity of your code.

Upvotes: 0

Dustin Davis
Dustin Davis

Reputation: 14605

When you "hide" a method from the base class using NEW you are just hiding it, thats it. It's still called when you explicitily call the base class implementation.

A doesnt contain WriteLine so you need to fix that. When I fixed it I got

Output from B
Output


namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            B writeClass = new B(); 
            writeClass.WriteLine("Output"); // I expect to see 'Output from B' 
            A otherClass = (A)writeClass; 
            otherClass.WriteLine("Output"); // I expect to see just 'Output' 
            Console.ReadKey();
        }
    }

    public class A
    {
        public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
    }
    public class B : A
    {
        public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
    }
}

Upvotes: 5

Jakub Konecki
Jakub Konecki

Reputation: 46018

Don't use new keyword when you override the method in class B. And declare the method in A as virtual.

Upvotes: 0

Related Questions