44

I have a static class with a static constructor. I need to pass a parameter somehow to this static class but I'm not sure how the best way is. What would you recommend?

public static class MyClass {

    static MyClass() {
        DoStuff("HardCodedParameter")
    }
}
Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54
MrProgram
  • 5,044
  • 13
  • 58
  • 98

4 Answers4

66

Don't use a static constructor, but a static initialization method:

public class A
{
    private static string ParamA { get; set; }

    public static void Init(string paramA)
    {
        ParamA = paramA;
    }
}

In C#, static constructors are parameterless, and there're few approaches to overcome this limitation. One is what I've suggested you above.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • but what is the point in using a method anyway, since there is a setter available... – meJustAndrew May 09 '18 at 11:26
  • 2
    @meJustAndrew Because that setter is `private`. Did you notice that important detail? :D – Matías Fidemraizer May 09 '18 at 12:58
  • 1
    @meJustAndrew Maybe another approach would be `ParamA { private get; set; }`... BTW it's just a code snippet to show you would initialize a static class with one or more parameters. Probably an unary constructor would be useless but just think that it's still useful if you want to cover the use case of giving it to some delegate... – Matías Fidemraizer May 09 '18 at 13:00
  • 1
    indeed, I haven't noticed that the property was `private`. I tried to find a way to initialize a static readonly field, from outside the class, and so I found your answer. Unfortunately it doesn't seem to be such a mechanism in C# right now. Sorry again, it was my fault for the comment above! – meJustAndrew May 09 '18 at 13:29
  • @meJustAndrew No problem :D Anyway, you can simulate what you want providing a `Lazy` instance instead of the value – Matías Fidemraizer May 09 '18 at 14:33
10

As per MSDN, A static constructor is called automatically to initialize the class before the first instance is created. Therefore you can't send any parameters.

CLR must call a static constructor, how will it know which parameters to pass it?

So don't use a static constructor.

Here's the work around for your requirement.

public class StaticClass 
{ 
  private int bar; 
  private static StaticClass _foo;

  private StaticClass() {}

  static StaticClass Create(int initialBar) 
  { 
    _foo = new StaticClass();
    _foo.bar = initialBar; 
    return _foo;
  } 
}

Static constructors have the following properties:

  • A static constructor does not take access modifiers or have parameters. A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
  • A static constructor cannot be called directly.
  • The user has no control on when the static constructor is executed in the program.
  • A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.
  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54
  • The method `Create` should be `public` to be called and initialize `StaticClass` . – M.Hassan Jan 15 '19 at 14:06
  • Can you explain your code a bit more? It appears to me that this is just a Singleton minus the null check to see if _foo is an object. Without that null check this would allow all callers of Create() to keep orphaning objects of StaticClass in memory as new instances are assigned to the static variable _foo, am I right? Thanks! – Stokely Oct 03 '21 at 13:07
0

If by "HardCodedParameter" you really mean hard coded, you can use constants.

public static class YoursClass
{ 
    public const string AnotherHardCodedParam = "Foo";
}

public static class MyClass
{
    private const string HardCodedParam = "FooBar";

    static MyClass()
    {
        DoStuff(MyClass.HardCodedParam);
        DoStuff(YoursClass.AnotherHardCodedParam);
    }
}

Also, you can use static readonly properties.

Mateusz Myślak
  • 775
  • 6
  • 16
0

Constructors on non-static class have have the benefit to ensure they're properly initialized before they're actually being used.

Since static classes don't have this benefit, you have to make ensure that yourself.

Use a static constructor with an obvious name, then in the relevant portion of your static procedures check to make sure the initialization has been performed. The example below assumes your want to "initialize" your static class with a Form object.

    public static class MyClass
    {
        private static Form FormMain { get; set; }

        public static void Init(Form initForm)
        {
            FormMain = initForm;
        }

        private static bool InitCheck()
        {
            return FormMain != null ? true: false;
        }

        public static void DoStuff()
        {
            if (InitCheck())
            {
                // Do your things
            }
            else
            {
                throw new Exception("Object reference not set to an instance of an object");
            }
        }
    }
GDavoli
  • 517
  • 4
  • 8