1

我目前正在思考一些我无法做到的想法。

问题是我想使用一个 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();
        }
    }
}
4

3 回答 3

5

你的意思是添加:

SqlCommand cmd = null;

(这解决了“确定分配”故障;它肯定被分配了......一个空值;-p 然后我们在使用它之前更新该值)。

但是,IMO,您最好使用嵌套using语句......并且(从代码中)不清楚实际连接来自哪里......

using(var conn = new SqlConnection(...))
using(var cmd = conn.CreateCommand()) {
    // ...
}
于 2009-06-10T09:17:09.260 回答
2

您只能通过在 using 块之前将 cmd 设置为 null 来避免这种情况:

    SqlCommand cmd=null;

    using (new DisposableComposite(
        () => cmd = new SqlCommand(),
        () => cmd.Connection)) // <- compiler error - variable not instantiated
    {
        // code
    }
于 2009-06-10T09:18:43.080 回答
0

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

另一种选择是定义一个新的 Context 类型对象,它在 Dispose 上处理它提供的所有对象。

例如。

using (var ctx = GetContext()) {
   var cmd = ctx.CreateCommand();
   cmd.Connection = ctx.CreateConnection();
}
// cmd is Disposed 
// cmd.Connection is Disposed 
于 2009-06-10T09:22:59.933 回答