Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle static fields that vary by implementing class

Tags:

java

c#

I hit this problem all the time. Suppose I am making a command line interface (Java or C#, the problem is the same I think, I will show C# here).

  1. I define an interface ICommand
  2. I create an abstract base class CommandBase which implements ICommand, to contain common code.
  3. I create several implementation classes, each extending the base class (and by extension the interface).

Now - suppose that the interface specifies that all commands implement the Name property and the Execute method...

For Name each of my instance classes must return a string that is the name of that command. That string ("HELP", "PRINT" etc) is static to the class concerned. What I would love to be able to do is define:

public abstract static const string Name;

However (sadly) you cannot define static members in an interface.

I have struggled with this issue for years now (pretty much any place I have a family of similar classes) and so will post my own 3 possible solutions below for your votes. However since none of them is ideal I am hoping someone will post a more elegant solution.


UPDATE:

  1. I can't get the code formatting to work properly (Safari/Mac?). Apologies.
  2. The example I am using is trivial. In real life there are sometimes dozens of implementing classes and several fields of this semi-static type (ie static to the implementing class).

  3. I forgot to mention - ideally I want to be able to query this information statically:

    string name = CommandHelp.Name;

2 of my 3 proposed solutions require that the class be instantiated before you can find out this static information which is ugly.

like image 873
Ewan Makepeace Avatar asked Sep 15 '08 20:09

Ewan Makepeace


2 Answers

You may consider to use attributes instead of fields.

[Command("HELP")]
class HelpCommand : ICommand
{
}
like image 169
Thomas Danecker Avatar answered Nov 15 '22 01:11

Thomas Danecker


As you mentioned, there is no way to enforce this from the interface level. Since you are using an abstract class, however, what you can do is declare the property as abstract in the base class which will force the inheriting class it override it. In C#, that would look like this:

public abstract class MyBaseClass
{
  public abstract string Name { get; protected set; }
}

public class MyClass : MyBaseClass
{
  public override string Name
  {
    get { return "CommandName"; }
    protected set { }
  }
}

(Note that the protected set prevents outside code changing the name.)

This may not be exactly what you're looking for, but it's as close as I think you can get. By definition, static fields do not vary; you simply can't have a member that is both static and overridable for a given class.

like image 31
Jeromy Irvine Avatar answered Nov 14 '22 23:11

Jeromy Irvine