C#:记某次using声明导致的问题
C#8.0引入了using声明(using declaration)特性,极大地简化了原本需要使用using语句(using statement)的代码。但该新特性并不意味着可以随处用using声明来替代旧的using语句写法,本文就是实践中的一次经历。
考虑创建一个压缩文件,其代码实现如下:
static byte[] ZipViaUsingDeclaration(string fileName, byte[] fileContent) { using var memoryStream = new System.IO.MemoryStream(); using var zipArchive = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, true); var entry = zipArchive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest); using var entryStream = entry.Open(); entryStream.Write(fileContent, 0, fileContent.Length); return memoryStream.ToArray(); } static byte[] ZipViaUsingStatement(string fileName, byte[] fileContent) { using (var memoryStream = new System.IO.MemoryStream()) { using (var zipArchive = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, true)) { var entry = zipArchive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest); using (var entryStream = entry.Open()) { entryStream.Write(fileContent, 0, fileContent.Length); } } return memoryStream.ToArray(); } }
测试表明,第二个方法能正常工作;第一个方法的结果不能解压为原内容。
为了让第一个方法正常工作,需要在退出前显式调用zipArchive.Dispose方法:
static byte[] ZipViaUsingDeclaration(string fileName, byte[] fileContent) { using var memoryStream = new System.IO.MemoryStream(); using var zipArchive = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, true); var entry = zipArchive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest); using var entryStream = entry.Open(); entryStream.Write(fileContent, 0, fileContent.Length); zipArchive.Dispose(); return memoryStream.ToArray(); }
文章[1] 更深入地讨论了这种现象,值得一读。
[1] “Be Careful with Using Declarations in C# 8”, Damir, https://www.damirscorner.com/blog/posts/20200103-BeCarefulWithUsingDeclarationsInCSharp8.html

浙公网安备 33010602011771号