如何重写一个通用方法?(C#)

3

我正在创建一个名为TetraQueue的类,该类继承了System.Collections.Generic.Queue类,并重写了Dequeue方法。以下是代码:

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

然而当我尝试编译这段代码时,我遇到了以下错误:

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

提前感谢您的帮助。

我该如何知道一个方法是否是虚拟的(以避免这种情况)?


我猜你是想说“Dequeue”而不是“Dequeque”吧?即使Dequeue是虚函数,你也无法以那种方式进行重写 :) 不过,如果我错了,我会让你编辑问题的。 - Jon Skeet
只是想指出,如果你想要重写的方法只是返回base.Dequeue(),那么它默认就会这样做,不需要尝试重写它。 - Chris Marisic
7个回答

9

判断一个方法是否是虚方法的两种方法:

  • 在Visual Studio中输入“override” - 它将为您提供所有可以重写的方法。
  • 查看文档 - Dequeue没有标明它是虚方法,因此无法重写它。

编辑:其他人建议隐藏该方法。我强烈建议您不要这样做,除非您确实必须这样做。这会导致调试会话变得困难,并且当继承的引用的编译时类型有所不同时,继承看起来有时有效,有时无效,这会让人感到沮丧。如果您不打算专门化行为,请使用组合而不是继承。


1
组合是一种被高度低估的技术。我总是会仔细思考是否需要继承或组合。 - kpollock

5
很遗憾,Dequeue方法不是虚方法,因此无法覆盖它。

5

你需要使用new关键字。这会告诉编译器你想让这个方法放在其他方法的顶部。但是请注意,如果你正在使用基类(例如Queue),你将无法使用这个新方法。

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

1
这是方法隐藏,而不是覆盖。有很大的区别。 - senfo

1

1

队列没有Dequeque方法,但有一个Dequeue方法。如果您修复了这个问题,仍然无法编译,因为它不是虚拟方法。

使用new关键字可以重新引入此方法,但请记住正确拼写函数名称,否则将会有一个.Dequeue和一个.Dequeque方法。

问题本身也包含了这个拼写错误。


1

覆盖一个方法只是为了调用父类是没有意义的,所以如果你发布的代码就是你要做的全部内容,那么不要覆盖它。

通过将TetraQueue作为Queue<TetraBlock>,您正在表示它可以在任何需要Queue<TetraBlock>的地方使用。通过添加一个新方法来隐藏原始方法(如果调用者知道它的TetraQueue),那么您就会破坏这个契约。

如果我想要与队列相同的行为,我会使用Queue<TetraBlock>; 如果我想要不同的东西,我会使用组合而不是继承。


我认为这个解释可以更详细地讲解两到三倍,但这已经是问题的核心了。 - Sol

1

正如先前提到的那样,您无法覆盖该方法,因为它是非虚拟的。但是,我强烈建议您不要隐藏该方法。请考虑以下内容:

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!");
        }
    }

对于不了解实现的人来说,这段代码的输出并不明显。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接