具有一次性成员的 C# ValueTuple

标签 c# using idisposable valuetuple

假设我有一个方法 foo,它返回一个 ValueTuple,其中一个成员是一次性的,例如 (IDisposable, int) .

确保调用方正确处理返回的一次性对象的最佳方法是什么?

我尝试了以下方法:

using (var (disposable, number) = foo())
{
    // do some stuff using disposable and number
}

但这不会编译:

'(IDisposable disposable, int number)': type used in a using statement must be implicitly convertible to 'System.IDisposable'

我真的需要将我的代码包装在一个 try-finally block 中并将我的对象明确地放置在 finally block 中,还是有更好的方法来做到这一点?

实际上,我希望看到新的 ValueTuples 实现 IDisposable 接口(interface)并在其所有一次性成员上调用 Dispose()。这对 Microsoft 来说是一个有值(value)的功能请求吗?

最佳答案

只需将方法调用移到 using 语句之外,然后使用一次性对象:

var (disposable, number) = foo();
using (disposable)
{
    // do some stuff using disposable and number
}

您的版本不起作用的原因很简单,无论 using 括号内的表达式结果需要是一次性的,但值元组本身不是一次性的。所以你只需要把它分开。幸运的是,using 语句不需要构造该表达式中的对象,您可以将任何现有对象传递给它。


Actually I'd like to see the new ValueTuples implement the IDisposable interface and call Dispose() on all their disposable members. Could this be a worthwhile feature request for Microsoft?

按照这个逻辑,所有 集合都必须这样做。例如,处理一个列表应该处理它的所有成员,处理一个字典应该处理它的所有值(和键?!?!)。当您的类型仅使用一个简单的列表时,该对象也需要是一次性的。

所以基本上,您最终会传播它并最终得到很多突然可以丢弃的对象,尽管它们实际上没有任何实际需要的资源

让元素成为一次性用品并非轻而易举的事。通常,创建一次性对象的对象负责稍后正确处置该对象,它们拥有该对象的生命周期。但对于收藏品,情况往往并非如此。集合通常只是这样的:保存对象的集合,但这并没有说明它们是否由集合拥有——大多数时候它们由同时创建的对象拥有集合,因此该对象应该在某个时候通过简单地遍历集合来处理对象。

关于具有一次性成员的 C# ValueTuple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46426432/

相关文章:

c# - 处理对象的代码分析友好方式

c# - 在缓存中存储 MemoryStream

c# - 如何以及何时处置 c# 静态成员?

c# - 如何在c#中格式化这个字符串

c# - Linq to entities if else 条件查询

c++ - 在 vs2015 的可变参数模板中找不到重载的成员函数

c# - 使用指令、命名空间和程序集引用——所有这些都与 StyleCop 混为一谈!

c# - 在 C# 中比较对象属性

c#类库使用文件

c# - 可以在 C# 中缩短数学引用吗?