我不明白以下现象,有人可以解释一下我的错误吗?
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实际上是拥有自己的静态变量的类型。但似乎该类的静态部分不是继承而是引用 - 我怎么会出错?
答案 0 :(得分:16)
只有一个静态Instance
属性,它在BaseClass
中定义,它也恰好是唯一可以更改它的类型(因为集合为private
)。
发生的事情是您的子类SubClassA
和SubClassB
各自在自己的构造函数中调用BaseClass
构造函数。此构造函数将Instance
设置为正在初始化的BaseClass
实例。
示例代码中的最后一个此类实例恰好是SubClassB
的实例;因此,当您到达Instance
来电时,一个 Console.WriteLine
属性会设置为此实例。
您可以撤消SubClassA
和SubClassB
个对象的构建,您会看到Instance
设置为SubClassA
的实例。
答案 1 :(得分:12)
.NET中的继承仅适用于实例库。静态方法是在类型级别上定义的,而不是在实例级别上定义的。这就是为什么覆盖不适用于静态方法/属性/事件......
静态方法只在内存中保存一次。没有为它们创建的虚拟表等。
如果在.NET中调用实例方法,则始终为其提供当前实例。这是.NET运行时隐藏的,但它确实发生了。每个实例方法都将第一个参数作为运行该方法的对象的指针(引用)。静态方法不会发生这种情况(因为它们是在类型级别定义的)。编译器应如何决定选择要调用的方法?
答案 2 :(得分:0)
由于存在这些问题,Singleton类应声明为密封:MSDN Singletons