【问题标题】:In C#, if a class or a method is not marked as sealed or virtual, what is it?在 C# 中,如果一个类或方法没有标记为密封或虚拟,那是什么?
【发布时间】:2014-06-11 00:56:25
【问题描述】:

换句话说,什么是默认值(如果没有指定)?我猜默认是虚拟的,因为即使基本方法没有指定虚拟,您也可以使用“new”关键字来覆盖基本方法。如果是这种情况,那么为什么我们甚至需要一个虚拟选项?当我们确实需要防止进一步继承时,我们不能只使用 Sealed 吗?

【问题讨论】:

标签: c# .net


【解决方案1】:

默认情况下,C# 方法是密封的——如果没有 virtual 关键字,您将无法覆盖它们。

new 关键字隐藏基类中的方法。

这就是我所说的隐藏的意思:

public class HidingA
{
    public string Get()
    {
        return "A";
    }
}

public class HidingB : HidingA
{
    public new string Get()
    {
        return "B";
    }
}

HidingA a = new HidingA();
HidingB b = new HidingB();

Console.WriteLine(a.Get()); // "A"
Console.WriteLine(b.Get()); // "B"

HidingA c = new HidingB();
Console.WriteLine(c.Get()); // "A". Since we're calling this instance of "B" an "A",    
                            //we're using the "A" implementation.

现在,虚拟版!

public class VirtualA
{
    public virtual string Get()
    {
        return "A";
    }
}

public class VirtualB : VirtualA
{
    public override string Get()
    {
        return "B";
    }
}
VirtualA a = new VirtualA();
VirtualB b = new VirtualB();

Console.WriteLine(a.Get()); // "A"
Console.WriteLine(b.Get()); // "B"

VirtualA c = new VirtualB();
Console.WriteLine(c.Get()); // "B". We overrode VirtualB.Get, so it's using the 
                            // "B" implementation of the method

因此,如果我们创建一个以HidingA 作为参数的方法并将HidingB 的实例传递给它,我们将获得Get 方法的HidingA 实现。

MSDN:http://msdn.microsoft.com/en-us/library/6fawty39.aspx

除非指定 sealed 关键字,否则类对继承开放。

【讨论】:

  • 我会提到 newoverride 之间的区别,但这是迄今为止最准确的答案。
  • 这没有回答关于类的问题;)
  • 谢谢。那么类默认是虚拟的呢?
  • C# 中不存在“虚拟”类,因为不允许多重继承。未密封的类可以被子类化,类中的虚方法可以在子类中被覆盖。
  • 抱歉有更多问题,但我正在努力深入了解。虚拟继承和多重继承之间有什么联系?即为什么虚拟在单继承中无关紧要?
【解决方案2】:

new 创建一个新方法(不覆盖它),其中一个被覆盖的方法将替换它,因此是virtual。正如上面 DanielM 所说,默认情况下方法是密封的。

这就是我们需要虚拟的原因:

   class Foo
   {
       public void Baz() { Assert("Foo.Baz"); }
   }

   class ChildOfFoo : Foo
   {
       public new void Baz() { Assert("ChildOfFoo.Baz"); }
   }

   Foo foo = new ChildOfFoo();
   foo.Baz(); // Foo.Baz

【讨论】:

  • 这没有回答所提出的问题。
猜你喜欢
  • 2022-09-25
  • 2012-05-19
  • 2011-04-06
  • 2011-06-12
  • 1970-01-01
  • 2019-09-24
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多