views:

158

answers:

3

I have two console apps, Query and Update, that share some functionality. I wanted to have the two classes inherit from a common base class, but the problem is that, for a console app, I have to have a static Main function. What I currently have is the following:

namespace Utils
{
    public class ConsoleBase
    {
        protected const int ERROR_EXIT_CODE = 1;
        protected static void printWarning(string msg) {...}
        public ConsoleBase(IEnumerable<string> args) { ... }
...

namespace Update
{
    class Update : ConsoleBase
    {
        private static ConsoleBase _consoleBase;
        public static void Main(string[] args) { ... }
...

namespace Query
{
    class Query : ConsoleBase
    {
        private static ConsoleBase _consoleBase;
        public static void Main(string[] args) { ... }
...

It seems like a design problem for me to both inherit from ConsoleBase as well as have an instance of it as a static variable within each derived class. The reason I'm doing this is so that:

  1. I can have protected static methods defined in ConsoleBase that are accessible to other static methods in the derived classes.
  2. I can pass along command-line arguments to the constructor for ConsoleBase, do common stuff, and then access the arguments again in the derived classes via public properties and methods on the instance of ConsoleBase.

So in the derived classes, I have a mixture of calls to methods/properties on the instance of ConsoleBase, e.g.

_consoleBase.UseDebugMode()

As well as calling inherited static methods and accessing inherited constants that are defined in ConsoleBase, e.g.

printWarning(CONST_MSG_IN_BASE_CLASS);

Can I clean this up somehow? Is it bad to both inherit from a class as well as keep an instance of that base class around for working with?

A: 

Yes you can define a base class with a protected static main, then call BaseClass.Main(args) from the Main method in the inheriting classes.

This syntex is more correct:

public class BaseApp
{
    public static Main(String[] args)
    {
        // TODO: ...
    }
}

public class App1 : BaseApp // Same for App2
{
    // There is no need to keep a reference of the base class
    // if you are accessing static methods only

    public static Main(String[] args)
    {
        BaseApp.Main(args); // Access via class, not via instance
    }
}
Danny Varod
+1  A: 

Don't mix static and instance methods like this.

Consider, separating the responsibility that the static methods provide into a different class that you can inherit from. Make the non-static functionality a separate class that you aggregate and instantiate within Update and Query.

Besides, if Update and Query are derivatives of ConsoleBase - why do you need the aggregate instances?

LBushkin
I like the idea of separating my `static` methods in `ConsoleBase` from the instance methods. Now, if I can think of good names for the two classes...
Sarah Vessels
A: 

I don't think you need to do that. Why don't you simply call the ConsoleBase.Main() function with your command line arguments?

Having an instance of the base class is a design problem.

Seth Illgard
I want the command-line arguments to be stored as instance variables since they won't be known until run-time. If I have a `static` Main function in `ConsoleBase`, I won't be able to access those instance variables in that `static` function.
Sarah Vessels