Search code examples
c#static-variableslazy-initialization

Static string variable with complex initialization in C#


I have a class with a static string variable that has a somewhat complex initialization (I can't just set it equal to a quoted string like "whatever"). I need to run a few lines of code to actually create the value. Once it gets set, its value won't change. It's currently set up as a property that just gets set on the first call to get.

class MyClass
{
    private static string _myString = "";
    public static string MyString
    {
        get
        {
            if(_myString == "")
            {
                // use an object "obj" here to create the value
                MyObject obj = new MyObject();
                obj.someSetupHere();
                _myString = obj.ToString();
            }
            return _myString;
        }
    }
}

My question is: is there a better way to do this? I would rather the value be set up when all the other variables get set, rather than on the first "get" of the value. Should I be using a Lazy<T> here instead? I would really like something like:

private static string _myString = 
{
        // use an object "obj" here to create the value
        MyObject obj = new MyObject();
        obj.someSetupHere();
        _myString = obj.ToString();
}

I know that's probably not valid syntax, but hopefully it conveys what I'm trying to do.


Solution

  • You can just call a method:

    private static readonly string _myString = GetMyStringValue();
    
    private static string GetMyStringValue()
    {
        MyObject obj = new MyObject();
        obj.someSetupHere();
        return obj.ToString();
    }
    

    You could do that all with a lambda expression cast to a Func<string> if you really wanted to avoid the extra declared method:

    private static readonly string _myString = ((Func<string>) () =>
    {
        MyObject obj = new MyObject();
        obj.someSetupHere();
        return obj.ToString();
    }).Invoke();
    

    Or use a static constructor to initialize the string:

    private static readonly string _myString;
    
    static MyClass()
    {
        MyObject obj = new MyObject();
        obj.someSetupHere();
        _myString = obj.ToString();
    }