在C#中,如果某个类或方法没有标记为密封或虚拟,那么它是什么?

时间:2014-06-10 16:22:40

标签: c# .net

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

2 个答案:

答案 0 :(得分:10)

默认密封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的实例,那么我们将获得HidingA Get的实现{1}}方法。

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

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

答案 1 :(得分:1)

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