views:

76

answers:

3

I don't understand the following phenomenon, could someone explain me please what I got wrong?

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();
    }
}

As I understood, the compiler should generate a new Type through inheritance, that SubClassA and SubClassB are really own types with own static variables. But it seems that the static part of the class is not inherited but referenced - what do i get wrong?

+1  A: 

Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...

Static methods are only held once in memory. There is no virtual table etc. that is created for them.

If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke?

Pranay Rana
I don't get it why inheritance only works on instances, but i have to accept it. Thank you for that info.
BeowulfOF
+9  A: 

There is only one static Instance property, and it is defined in BaseClass, which also happens to be the only type that can change it (since the set is private).

What's happening is that your subclasses SubClassA and SubClassB each invoke the BaseClass constructor in their own constructors. This constructor sets Instance to the BaseClass instance being initialized.

The last such instance in your example code happens to be an instance of SubClassB; hence the one Instance property is set to this instance by the time you reach your Console.WriteLine calls.

You could reverse the construction of your SubClassA and SubClassB objects and you would see Instance set to an instance of SubClassA instead.

Dan Tao
+1 for also explaining why it writes SubClassB twice
Sander Rijken
A: 

Because of such problems, Singleton classes should be declared sealed: MSDN Singletons

testalino