static abstract class

22,310

Solution 1

You could make non-static classes that follow singleton, ensuring only one instance of the object ever to exist. I guess that could be the next best thing.

Solution 2

You can't want static and inheritance at the same time ! It simply does not make sense !

If you need to override behavior, you need inheritance !

If you want simplicity of call (one of the advantage of statics), you can use Factory (or singleton if only one instance is needed)

My guess is that you probably have to rethink your model. This set of constants of yours probably represent something that you could extract in a separate class then pass this class to your static method. Would that fit your needs ?

Solution 3

Edit

To your code sample:

public abstract static class Calculation
{
    public static int Constant { get; set; }
    public static int Calculate(int i) { return i * Constant; }
}

// ...

Calculation.Constant = 6;
Calculation.Calculate(123);

Somewhat more general:

public abstract static class Calculation
{
    public struct Context
    {
        public int Constant, SignificantDigits;
        public bool Radians;
    }
    public static int Calculate(int i, Context ctx) { return i * ctx.Constant; }
}

// ...
Calculation.Calculate(123, new Calculate.Context { Constant = 6 });

First idea:

The closest I can think of is generics:

public interface ISpecifics
{ 
     void DoSomething();
     string SomeProp { get; }
}

public static class Static<S> 
    where S : ISpecifics, new()
{

      public static string ExerciseSpecific()
      {
            var spec = new S();
            spec.DoSomething();
            return spec.SomeProp;
      }
}

Or if you really need a single static type

public static class Static
{
      public static string ExerciseSpecific<S>()
          where S : ISpecifics, new()
      {
            var spec = new S();
            spec.DoSomething();
            return spec.SomeProp;
      }
}

Does that help?

Share:
22,310
David Božjak
Author by

David Božjak

Tech Manager at Storytel in Lund, Sweden.

Updated on December 19, 2020

Comments

  • David Božjak
    David Božjak over 3 years

    I need a way to create a static class where some constants can be case specific, but hard-coded.

    What I really want to do is have a class where several constants are provided when the class is extended - I want the 'constants' hard-coded. I figured I will make the some abstract properties and define the get { return constant; } when extending the class.

    I know that is not possible, so now I am facing two options and am wondering what would be best and why (if there are options I'm missing please let me know!)

    1. Create a static class with nullable fields and throw an exception if the fields are null when the static method is called.
    2. Give up the static class. Have a non-static class with abstract properties and create an instance of the object wherever I need it even though all the functionality really is static.

    I know this might be subjective and case-dependant, however I am going around in circles when thinking about this and could really do with some external input. That plus I hope there might be away of doing what I want and I'm just thinking about this wrong.

    Update: Code: I will try to write some code that describes what I'd like to accomplish. I know this code can't work!

    Imagine that the abstract class Calculation is in a dll, used by many projects. The functionality is the same for all of them, just the Constant varies from project to project.

    public abstract static class Calculation
    {
        private abstract int Constant { get; }    //The constant is unknown at this time
    
        public static int Calculate(int inputValue)
        {
            return inputValue * Constant;
        }
    }
    

    The class Calc is defined in a separate project where the functionality is needed and the Constant is known.

    public static class Calc : Calculation
    {
        private override int Constant { get { return 2; }
    }
    
    ...
    
    static class Program
    {
        [STAThread]
        static void Main()
        {
            //At some point:
            int result = Calc.Calculate(6);
        }
    }
    

    I suppose the simplest way would be to create a non-static class and create an instance, however I fear having several instances of the class could be expensive and would like to prevent that if possible.

    I can't see how I could write this as a singleton pattern without writing it again in each project - having only the Nested class in the dll. That doesn't prevent the implementor to just create an ordinary class and is likely to restart the debate for every project where the code is used.

    Update #2 : What I ment with option one is this:

    Class in a dll:

    public static class Calculation 
    {
        public int? Constant {get; set;}
    
        public static int Calculate(int inputValue)
        {
            if (Constant == null)
                throw new ArgumentNullException();
    
            return inputValue * (int)Constant;
        }
    }
    

    Usage of the function in a seperate project:

    static class Program
    {
        [STAThread]
        static void Main()
        {
            //At some point:
            Calculation.Constant = 2;
            int result = Calc.Calculate(6);
        }
    }
    

    Option one is very simple and elegant, what bothers me about it that nothing forces the implementor to set the Constant. I fear an (admittedly unlikely) scenario where an obscure corner case will cause the property to not be set and for the code to fail (and Constant beeing the last suspect)...