代码之家  ›  专栏  ›  技术社区  ›  VVS

捕获变量实例化问题

  •  1
  • VVS  · 技术社区  · 17 年前

    我现在正在思考一些我不能正确理解的想法。

    问题是我想用一个lambda函数实例化一个捕获的变量,用另一个lambda函数访问该变量的属性。

    由于实例化发生在lambda中,因此在我希望在第二个lambda中使用变量时,该变量实际上没有实例化。。这是一个鸡和蛋的问题。

    我知道这个变量 将 实例化了在第二个lambda中使用它的时间,但编译器没有。

    有没有办法让我的想法奏效?以下是实际代码:

    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();
            }
        }
    }
    
    3 回复  |  直到 16 年前
        1
  •  5
  •   Marc Gravell    17 年前

    你的意思是仅仅添加:

    SqlCommand cmd = null;
    

    (这解决了“确定分配”的小故障;它 是 明确指定。。。空值-p然后在使用之前更新该值)。

    不过在我看来,你最好用嵌套的 using

    using(var conn = new SqlConnection(...))
    using(var cmd = conn.CreateCommand()) {
        // ...
    }
    
        2
  •  2
  •   VVS    17 年前

    只有在使用块之前将cmd设置为null,才能避免这种情况:

        SqlCommand cmd=null;
    
        using (new DisposableComposite(
            () => cmd = new SqlCommand(),
            () => cmd.Connection)) // <- compiler error - variable not instantiated
        {
            // code
        }
    
        3
  •  0
  •   Sam Saffron James Allen    17 年前

    同意马克的观点,这感觉不太对。

    另一个选项是定义一个新的上下文类型对象,该对象在Dispose上处理它提供的所有对象。

    如。

    using (var ctx = GetContext()) {
       var cmd = ctx.CreateCommand();
       cmd.Connection = ctx.CreateConnection();
    }
    // cmd is Disposed 
    // cmd.Connection is Disposed