c# - 我可以在 using 语句中安全地使用对象初始化器吗?
问题描述
我想知道在 using 语句中使用对象初始化器是否会以某种方式阻止正确处理其中声明的资源,例如
using (Disposable resource = new Disposable() { Property = property })
{
// ...
}
我读过对象初始化器只不过是同步糖,编译器将其转换为类似于以下代码的内容:
MyClass tmp = new MyClass();
tmp.Property1 = 1;
tmp.Property2 = 2;
actualObjectYouWantToInitialize = tmp;
即使我可能看起来像一个困惑的无知,我也想要求澄清。初始化对象(据我所知)是指向另一个对象的指针(据我所知,这也是一个指针)这一事实是否会干扰using
语句对资源的处理?
解决方案
主要(唯一?)危险是,如果设置Property
失败(即抛出异常),则resource
不会是Dispose
d。
using (Disposable resource = new Disposable() { Property = property })
{
// ...
}
通常using
,块中的异常是可以的——因为 .using
是try .. finally
.
这里的问题是,当你有效地Property = property
执行时,你还没有“在”块内。这与构造函数抛出异常时发生的情况本质上没有什么不同。using
finally
块将尝试的事情Dispose
是resource
- 但resource
从未设置 - resource
(如您的actualObjectYouWantToInitialize
示例所示)是在属性全部设置之后设置的 。
https://dotnetfiddle.net/vHeu2F展示了这在实践中是如何发生的。请注意Dispose
,即使有两个using
块,它也记录了一次。
using System;
namespace Bob
{
public class Disposable : IDisposable
{
private int _property;
public int Property { get => _property; set => throw new Exception(); }
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("1");
using (var resource = new Disposable())
{
Console.WriteLine("2");
}
Console.WriteLine("3");
using (var resource = new Disposable() { Property = 1 })
{
Console.WriteLine("4");
}
Console.WriteLine("5");
}
}
}
CA2000可能有助于检测此问题。
推荐阅读
- ios - 带有 UISegmentControl 的 UITextField 会导致额外的键盘通知吗?
- mysql - 使用 MySQL Workbench 时 MySQL 出现错误 #1064
- google-tag-manager - dataLayer.push 不会触发请求
- rust - 如何使用 &'static dyn Any 值将非静态值插入静态 HashMap?
- javascript - 如何使用 Chrome 上下文菜单编辑图像
- pandas - Pandas 映射函数在某些单元格中返回“NaN”
- javascript - 如何在 disccord.js 中获取/获取最近创建的频道?
- arrays - MethodError: 没有方法匹配权重(::Array{Any,1}, ::Float64)
- javascript - 显示 2% 符号的 Highcharts 饼图
- java - 为什么当我尝试执行时我的查询显示 javalang