tags:

views:

1319

answers:

3

Static inheritance works just like instance inheritance. Except you are not allowed to make static methods virtual or abstract.

class Program {
    static void Main(string[] args) {
        TestBase.TargetMethod();
        TestChild.TargetMethod();
        TestBase.Operation();
        TestChild.Operation();
    }
}

class TestBase {
    public static void TargetMethod() {
        Console.WriteLine("Base class");
    }

    public static void Operation() {
        TargetMethod();
    }
}

class TestChild : TestBase {
    public static new void TargetMethod() {
        Console.WriteLine("Child class");
    }
}

This will output:

Base class
Child class
Base class
Base class

But I want:

Base class
Child class
Base class
Child class

If it I could on static methods, I would make TargetMethod virtual and it would do the job. But is there a work around to get the same effect?

Edit: Yes, I could put a copy of Operation in the child class, but this would require copy and pasting a large bit of code into every child, which in my case is about 35 classes, a maintenance nightmare.

+5  A: 

No, you cannot override a static method. "static" also means that it is statically bound by the compiler, so the actual method to be called is not found at runtime, but bound at compile time.

What you should do is make the class non-static. Make the method virtual and override it and make full benefit of real inheritance. Then, if you really need it, make a static entry point to a reference of your class. For instance a static factory, singleton (it's an anti-pattern in most of the cases but is as good as a static class) or just a static property.

Stefan Steinegger
+1  A: 

You could store the TargetMethod as a delegate, which a subclass could change as needed:

class TestBase {
    protected static Action _targetMethod;

    static new() {
       _targetMethod = new Action(() => {
           Console.WriteLine("Base class");
       });
    }

    public static void TargetMethod() {
        _targetMethod();
    }

    public static void Operation() {
        TargetMethod();
    }
}

class TestChild : TestBase {
    static new() {
       _targetMethod = new Action(() => {
           Console.WriteLine("Child class");
       });
    }
}

Since these are static instances, though - the _targetMethod is shared across all instances - changing it in TestChild changes it for TestBase as well. You may or may not care about that. If you do, generics or a Dictionary<Type, Action> might help.

Overall, though, you'd have a much easier time if you didn't insist on statics, or perhaps used composition instead of inheritance.

Mark Brackett
A: 

If you are looking to do abstract static methods, then this works, and turns out to be the easiest solution for me to adapt to:

class TestBase<ChildType> where ChildType : TestBase<ChildType> {
    //public static abstract void TargetMethod();

    public static void Operation() {
        typeof(ChildType).GetMethod("TargetMethod").Invoke(null, null);
    }
}

class TestChild : TestBase<TestChild> {
    public static void TargetMethod() {
        Console.WriteLine("Child class");
    }
}

But I am still marking Stafan as the solution because using instance inheritance is probably the best recommendation for anyone in a similar situation. But I simply would have to rewrite too much code for it.

Nick Whaley