gpt4 book ai didi

c# - 有没有办法告诉编译器将始终执行特定代码块?

转载 作者:太空狗 更新时间:2023-10-30 01:01:11 24 4
gpt4 key购买 nike

我们的代码库中有以下构造,用于确保特定资源在使用后得到处理:

using (var disposableThing = DisposableThing.Begin())
{
// do something

disposableThing.Finish(); // must always be called
}

这是它的用法示例:

List<int> ids;

using (var disposableThing = DisposableThing.Begin())
{
ids = disposableThing.GetSomeIds();

disposableThing.Finish();
}

DoSomethingElseWith(ids);

由于这种模式很常见,我们在 DisposableThing 上写了一个方法封装它:

static void ExecuteWithFinish(Action<DisposableThing> action)
{
using (var disposableThing = Begin())
{
action(disposableThing);

disposableThing.Finish();
}
}

这允许我们将第二个示例重写为:

// #4
List<int> ids;

DisposableThing.ExecuteWithFinish(disposableThing =>
{
ids = disposableThing.GetSomeIds();
});

DoSomethingElseWith(ids); // compiler error "Use of unassigned local variable 'ids'"

但编译器拒绝编译该代码,因为它无法知道 ids将始终在 ExecuteWithFinish 之后分配已完成(或抛出异常,无论如何都会阻止 DoSomethingElseWith 的执行)。

  • 我知道我可以添加 ExecuteWithFinish 的重载从传入的 Func 返回值, 这很丑。
  • 我知道我可以继承 DisposableThing并覆盖它的 Dispose调用方法 Finish ,这是一种比每次都构造一个委托(delegate)更干净、更整洁、更快的方法(这可能是我最终会做的)。

但为了我自己的启迪和“假设”的精神,是否有可能通知甚至欺骗编译器允许#4 中编写的代码?

编辑: 是的,我知道我可以写 List<int> ids = null;并完全规避这个问题,但是 (a) 我不想执行不必要的分配 (b) 我想尽可能少地更改代码。

最佳答案

我会在这里采取不同的方法。

我将假设由于某种原因,您必须有一个必须始终在 Dispose() 之前调用的 Finish() 方法,该方法也必须总是被调用。

这可能是一个轻率的假设,它确实在回避问题:为什么不将 Finish() 的功能放入 Dispose() 中?然而……

首先,创建一个接口(interface),用 Finish() 方法封装一个一次性的东西:

public interface IDisposableThingWithFinish : IDisposable
{
void Finish();
}

并更改您的 DisposableThing 类,使其实现 IDisposableThingWithFinish

然后您可以编写一个封装调用 Finish()Dispose() 的一次性类,如下所示:

public sealed class DisposingFinisher : IDisposable
{
readonly IDisposableThingWithFinish _item;

public Disposing(IDisposableThingWithFinish item)
{
if (item == null)
throw new ArgumentNullException(nameof(item));

_item = item;
}

public void Dispose()
{
try
{
_item.Finish();
}

finally
{
_item.Dispose();
}
}
}

您可以像这样使用 Finisher:

using (var disposableThing = new DisposingFinisher(DisposableThing.Begin()))
{
// Do something.
}

关于c# - 有没有办法告诉编译器将始终执行特定代码块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40889341/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com