继承和静态属性

时间:2010-09-23 07:47:26

标签: c# .net oop inheritance

我不明白以下现象,有人可以解释一下我的错误吗?

public class BaseClass
{
    public BaseClass()
    {
        BaseClass.Instance = this;
    }

    public static BaseClass Instance
    {
        get;
        private set;
    }
}

public class SubClassA : BaseClass
{
    public SubClassA() 
        : base()
    { }
}

public class SubClassB : BaseClass
{
    public SubClassB()
        : base()
    { }
}

class Program
{
    static void Main(string[] args)
    {
        SubClassA a = new SubClassA();
        SubClassB b = new SubClassB();

        Console.WriteLine(SubClassA.Instance.GetType());
        Console.WriteLine(SubClassB.Instance.GetType());

        Console.Read();
    }
}

据我所知,编译器应该通过继承生成一个新的Type,SubClassA和SubClassB实际上是拥有自己的静态变量的类型。但似乎该类的静态部分不是继承而是引用 - 我怎么会出错?

3 个答案:

答案 0 :(得分:16)

只有一个静态Instance属性,它在BaseClass中定义,它也恰好是唯一可以更改它的类型(因为集合为private)。

发生的事情是您的子类SubClassASubClassB各自在自己的构造函数中调用BaseClass构造函数。此构造函数将Instance设置为正在初始化的BaseClass实例。

示例代码中的最后一个此类实例恰好是SubClassB的实例;因此,当您到达Instance来电时,一个 Console.WriteLine属性会设置为此实例。

您可以撤消SubClassASubClassB个对象的构建,您会看到Instance设置为SubClassA的实例。

答案 1 :(得分:12)

.NET中的继承仅适用于实例库。静态方法是在类型级别上定义的,而不是在实例级别上定义的。这就是为什么覆盖不适用于静态方法/属性/事件......

静态方法只在内存中保存一次。没有为它们创建的虚拟表等。

如果在.NET中调用实例方法,则始终为其提供当前实例。这是.NET运行时隐藏的,但它确实发生了。每个实例方法都将第一个参数作为运行该方法的对象的指针(引用)。静态方法不会发生这种情况(因为它们是在类型级别定义的)。编译器应如何决定选择要调用的方法?

答案 2 :(得分:0)

由于存在这些问题,Singleton类应声明为密封:MSDN Singletons