views:

223

answers:

2

Hello, I've some classes like this

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public virtual void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public override void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

It works correctly, prints "METHOD FROM C"

BUT

if I've a situation like this

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public new void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

it prints "METHOD FROM A". How can I obtain the same behaviour of first example without adopt cast or change method declaration with override?

+11  A: 

You can't - this difference in behaviour is the whole point of using virtual/override.

When you declare a method with "new" you're saying "I know that I am hiding a method with the same signature rather than overriding it; I don't want polymorphic behaviour."

Likewise when you declare a method without specifying "virtual" you're saying "I don't want subclasses to be able to override this method."

Why do you want to do this? Are you actually just trying to override a method which hasn't been declared virtual? If so, there's no way round it - and for good reason. If the author hasn't designed the class with polymorphism in mind, it could easily break if you were able to override the method.

Of course, if you declare the variable to be of the type of the subclass, like this:

C c = new C();
c.method();

then that will invoke the newly declared method.

Jon Skeet
+1 I couldn't have explained better than that! =)
Will Marcouiller
+1  A: 

Like Jon said avoid it. But

static void Main(string[] args)
    {
        A a = new C();

        (a as C).method();

        Console.ReadLine();
    }
TheMachineCharmer