views:

93

answers:

6

This is a interview question. So is it possible to override a method without virtual specified in parent method?

A: 

No, it would be function hiding.

DevDemon
A: 

The "new" keyword can hide a method defined in a base class when you access that method through a compile-time reference of type T such that typeof(DerivedClass).IsAssignableFrom(typeof(T)). You can not truly override it, however. References that use the base type at compile time will always call the base method regardless of what you do in the definition of the derived class.

If I were asked that question in an interview, that's what I would say. If I were asking it, that's the answer I'd hope for. Anyone who thinks that "new" is the same as "override" and doesn't qualify their answer somehow doesn't understand what "virtual" means or how vtables work (conceptually or mechanically).

blucz
Ok thanks. So strictly speaking ,we cant override using new. I guess the interviewer wanted to know about new keyword.
nash
+2  A: 

Technically you cannot override the method. You can hide it, though, using the new keyword:

class Foo
{
    public void Bar() {}
}

class FooChild : Foo
{
    new public void Bar() {}
}

The catch is that when you call Bar() from the base class (or if you cast FooChild to Foo), it will execute the base class' code - not the "new" code.

Jon B
+6  A: 

They probably wanted you to say "Use the new keyword to hide the method." Which technically does not override the method. If you have

class Base
{
    public void Bar() { Console.WriteLine("Base"); }
}

class Derived : Base
{
    public new void Bar() { Console.WriteLine("Derived"); }
}

And then you wrote

Derived derived = new Derived();
derived.Bar();
((Base)derived).Bar();

You would see different results. So functions that use the base class would get the results for the base method, and functions that use the derived class would get the results for the new method.

Anthony Pegram
A: 

If overriding non-virtual public methods was possible, we would have much more powerful mocking frameworks. No, it's not possible to override non-virtual members, only hide them using new keyword.

Igor Zevaka
A: 

The following is not overriding. Also, please never do this for real. It's a "trick" to provide an alternative behaviour, though:

class Base
{
    protected Action m_action;

    public Base()
    {
        m_action = () => Console.WriteLine("Base Class");
    }
    public void NonVirtual()
    {
        m_action();
    }
}

class Derived : Base
{
    public Derived()
    {
        m_action = () => Console.WriteLine("Derived Class");
    }
}

class Program
{
    static void Main (string[] args)
    {
        Base baseClass = new Base();
        Derived derivedClass = new Derived();
        Base derivedAsBase = derivedClass;

        Console.WriteLine("Calling Base:");
        baseClass.NonVirtual();

        Console.WriteLine("Calling Derived:");
        derivedClass.NonVirtual();

        Console.WriteLine("Calling Derived as Base:");
        derivedAsBase.NonVirtual();

        Console.ReadKey();
    }
}

Result:

Calling Base:
Base Class
Calling Derived:
Derived Class
Calling Derived as Base:
Derived Class

Edit: Although I say it's a trick, it could be tidied up into the Strategy pattern or similar.

Giraffe
Let me clarify a little. If we could alter the base class to implement this, then there's no problem making the method virtual. If the base class author has thought ahead of time to put this hook in then they probably should have done it by providing an overridable method. This is really just a silly answer to a silly question but would demonstrate "thinking outside the box" in an interview, perhaps?
Giraffe
well this shows the power of dynamic language features plus how easily it can be misused
nash