Diones
Diones

Reputation: 1481

How do I override an generic method?(C#)

I'm creating a class named TetraQueue that inherits System.Collections.Generic.Queue class overriding the Dequeue method, here is the code:

public class TetraQueue : Queue<Tetrablock>
{
   public override Tetrablock Dequeue()
   {
       return base.Dequeue();
   }
 }

But when I try to compile this I get:

Error TetraQueue.Dequeue()': no suitable method found to override TetraQueue.cs

Thanks in advance.

How do I know if a method is virtual(to avoid this kind of situation)?

Upvotes: 3

Views: 4012

Answers (7)

Pete Kirkham
Pete Kirkham

Reputation: 49311

It is pointless to override a method to only call the parent, so if the code you posted is all you're doing, then don't override it.

By making your TetraQueue a Queue<TetraBlock> you're saying it can be used whenever a Queue<TetraBlock> can be. By adding a new method to it which hides the original method if the caller knows its TetraQueue, then you're messing with that contract.

If I wanted the same behaviour as Queue I'd use a Queue<TetraBlock>; if I wanted something different I'd use composition rather than inheritance.

Upvotes: 1

senfo
senfo

Reputation: 29036

As has been previously mentioned, you cannot override the method because it is non-virtual. However, I would strongly urge you not to hide the method. Consider the following:

class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            A c = new B();

            // Straight A
            a.MyVirtualMethod();
            a.MyNonVirtualMethod();

            // Straight B
            b.MyVirtualMethod();
            b.MyNonVirtualMethod();

            // Polymorphic
            c.MyVirtualMethod();
            c.MyNonVirtualMethod();

            Console.ReadLine();
        }
    }

    public class A
    {
        public virtual void MyVirtualMethod()
        {
            Console.WriteLine("Hello world!");
        }

        public void MyNonVirtualMethod()
        {
            Console.WriteLine("Hello world!");
        }
    }

    public class B : A
    {
        public override void MyVirtualMethod()
        {
            Console.WriteLine("Good bye universe!");
        }

        public new void MyNonVirtualMethod()
        {
            Console.WriteLine("Good bye universe!");
        }
    }

The output of this code is not obvious to somebody that doesn't understand the implementation.

Hello world!
Hello world!
Good bye universe!
Good bye universe!
Good bye universe!
Hello world!

Upvotes: 1

Andrew Hare
Andrew Hare

Reputation: 351526

Unfortunately the Dequeue method is not virtual so you can't override it.

Upvotes: 5

Davy Landman
Davy Landman

Reputation: 15439

Queue has no Dequeque method but a Dequeue method. That would be the first compile error, if you fix that, you still can't compile because it's not a virtual method.

Using the new keyword you could reintroduce this method, but remember to spell the function name correct, or there will be a .Dequeue and a .Dequeque method.

The question itself also contains this spelling error.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500675

Two ways to know whether or not a method is virtual:

  • Type in "override" in Visual Studio - it will offer you all the methods you're allowed to override.
  • View the documentation - Dequeue doesn't say it's virtual, so you can't override it.

EDIT: Others have suggested hiding the method. I strongly recommend that you don't do that unless you really, really have to. It's a recipe for difficult debugging sessions and frustration when inheritance appears to sometimes work and sometimes not, depending on the compile-time type of the reference. Blurgh. If you're not going to specialize the behaviour, use composition instead of inheritance.

Upvotes: 9

Nick Berardi
Nick Berardi

Reputation: 54854

you have to use the new keyword. This will tell the compiler that you want this method put on top of the other one. Just a warning though, if you are using the base class such as Queue you will not be able to use this new method.

public class TetraQueque : Queue<Tetrablock>
{
   public new Tetrablock Dequeque()
   {
       return base.Dequeue();
   }
}

Upvotes: 5

Gerrie Schenck
Gerrie Schenck

Reputation: 22368

Add the new keyword to hide the method on the base class.

A good article on the polymorphism in .net: http://www.akadia.com/services/dotnet_polymorphism.html

Upvotes: 1

Related Questions