捕获变量实例化问题

发布于 2024-07-23 12:11:06 字数 1149 浏览 4 评论 0原文

我目前正在思考一些我无法理解的想法。

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

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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

亽野灬性zι浪 2024-07-30 12:11:06

您的意思是只是添加:(

SqlCommand cmd = null;

这解决了“明确分配”故障;它明确分配... null ;-p 然后我们在使用该值之前更新该值)。

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

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

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()) {
    // ...
}
‘画卷フ 2024-07-30 12:11:06

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

    SqlCommand cmd=null;

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

You can only avoid this by setting cmd to null before the using block:

    SqlCommand cmd=null;

    using (new DisposableComposite(
        () => cmd = new SqlCommand(),
        () => cmd.Connection)) // <- compiler error - variable not instantiated
    {
        // code
    }
灼痛 2024-07-30 12:11:06

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

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

例如。

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

Agree with Marc that this does not really feel right.

Another option would be to define a new Context type object, that on Dispose disposes all the objects it provides.

Eg.

using (var ctx = GetContext()) {
   var cmd = ctx.CreateCommand();
   cmd.Connection = ctx.CreateConnection();
}
// cmd is Disposed 
// cmd.Connection is Disposed 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文