Search code examples
c#lambdacaptured-variable

Captured variable instantiating problem


I'm currently musing about some idea I can't get right.

The problem is that I want to use one lambda function to instantiate a captured variable and another lambda to access a property of that variable.

Since the instantiating happens within the lambda the variable isn't actually instantiated the time I want to use it within the second lambda.. this is kind of a chicken and egg problem.

I know that the variable will be instantiated the time it's used in the second lambda but the compiler doesn't.

Is there any way my idea could work? Here's the actual code:

class Program
{
    static void Main(string[] args)
    {
        SqlCommand cmd;

        using (new DisposableComposite(
            () => cmd = new SqlCommand(),
            () => cmd.Connection)) // <- compiler error - variable not instantiated
        {
            // code
        }
    }
}

class DisposableComposite : IDisposable
{
    private List<IDisposable> _disposables = new List<IDisposable>();

    public DisposableComposite(params Func<IDisposable>[] disposableFuncs)
    {
        // ensure the code is actually executed
        foreach (var func in disposableFuncs)
        {
            IDisposable obj = func.Invoke();
            _disposables.Add(obj);
        }
    }

    public void Dispose()
    {
        foreach (var disposable in _disposables)
        {
            disposable.Dispose();
        }
    }
}

Solution

  • Do you mean just adding:

    SqlCommand cmd = null;
    

    (which solves the "definite assignment" glitch; it is definitely assigned... a null ;-p We then update the value before it is used).

    IMO, though, you'd do better with nested using statements... and it isn't clear (from the code) where the actual connection is going to come from...

    using(var conn = new SqlConnection(...))
    using(var cmd = conn.CreateCommand()) {
        // ...
    }