Search code examples
c#lazy-initialization

LazyAction in C#?


Is there a way in the C# standard API to lazily initialize a block of code?

I know Lazy<T> but it is meant to initialize one variable, and requires a function that returns a T. I'd like something that's more like a LazyAction.

private _lazyInit = new LazyAction( () => {
    ...
    // Do something big like get some data from DB
    ...
    _myField1 = ...
    _myField2 = ...
    ...
    do no return stuff.
}

public object get_Field1() { _lazyInit.EnsureDone(); return _myfield1; }
public object get_Field2() { _lazyInit.EnsureDone(); return _myfield2; }

For thread-safety, the LazyAction would have some mechanism to ensure it's only run once.


Solution

  • Although I like Jeroen Mostert's proposal better, you could do something like this:

    create a class that holds your initialization method:

    class LazyInitializer
    {
        private readonly Action initFunc;
    
        class State { public bool Initialized = false; }
    
        public LazyInitializer(Action initFunc)
        {
            this.initFunc = initFunc;
        }
    
        public Action CreateInitializer()
        {
            var state = new State();
    
            return () =>
            {
                lock (state)
                {
                    if (state.Initialized == false)
                    {
                        initFunc();
                        state.Initialized = true;
                    }
                }
            };
        }
    }
    

    and then use it like:

    var lazyInit = new LazyInitializer(() =>
    {
        //here your initialization code
        ...
        _myField1 = ...
        _myField2 = ...
        ...
    });
    
    //Create the initializer action
    var initialize = lazyInit.CreateInitializer();
    
    //use it like:
    public object get_Field1() { initialize(); return _myfield1; }
    public object get_Field2() { initialize(); return _myfield2; }