在 C# 中嵌套 using 语句

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1329739/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:12:54  来源:igfitidea点击:

Nested using statements in C#

c#.netfileusing

提问by SBurris

I am working on a project. I have to compare the contents of two files and see if they match each other precisely.

我正在做一个项目。我必须比较两个文件的内容,看看它们是否精确匹配。

Before a lot of error-checking and validation, my first draft is:

在大量的错误检查和验证之前,我的初稿是:

  DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + "\TestArea\");
  FileInfo[] files = di.GetFiles(filename + ".*");

  FileInfo outputFile = files.Where(f => f.Extension == ".out").Single<FileInfo>();
  FileInfo expectedFile = files.Where(f => f.Extension == ".exp").Single <FileInfo>();

  using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
  {
    using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
    {
      while (!(outFile.EndOfStream || expFile.EndOfStream))
      {
        if (outFile.ReadLine() != expFile.ReadLine())
        {
          return false;
        }
      }
      return (outFile.EndOfStream && expFile.EndOfStream);
    }
  }

It seems a little odd to have nested usingstatements.

嵌套using语句似乎有点奇怪。

Is there a better way to do this?

有一个更好的方法吗?

采纳答案by SLaks

The preferred way to do this is to only put an opening brace {after the last usingstatement, like this:

执行此操作的首选方法是仅{在最后一条using语句之后放置一个左大括号,如下所示:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead())) 
{
    ///...
}

回答by Gavin H

If the objects are of the same typeyou can do the following

如果对象的类型相同,您可以执行以下操作

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()), 
                    expFile = new StreamReader(expectedFile.OpenRead()))
{
    // ...
}

回答by womp

There's nothing odd about it. usingis a shorthand way of ensuring the disposal of the object once the code block is finished. If you have a disposable object in your outer block that the inner block needs to use, this is perfectly acceptable.

这没有什么奇怪的。 using是确保代码块完成后处理对象的速记方式。如果您的外部块中有一个内部块需要使用的一次性物品,这是完全可以接受的。

Edit: Too slow on the typing to show consolidated code example. +1 to everyone else.

编辑:打字太慢,无法显示统一的代码示例。+1 给其他人。

回答by jason

When the IDisposables are of the same type, you can do the following:

IDisposables 的类型相同时,您可以执行以下操作:

 using (StreamReader outFile = new StreamReader(outputFile.OpenRead()), 
     expFile = new StreamReader(expectedFile.OpenRead()) {
     // ...
 }

The MSDN page on usinghas documentation on this language feature.

MSDN 页面上using有关于此语言功能的文档。

You can do the following whether or not the IDisposables are of the same type:

无论IDisposables 是否属于同一类型,您都可以执行以下操作:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamWriter anotherFile = new StreamReader(anotherFile.OpenRead()))
{ 
     // ...
}

回答by codymanix

You can group multiple disposable objects in one using-statement with commas:

您可以使用逗号将多个一次性对象分组到一个 using 语句中:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()), 
       expFile = new StreamReader(expectedFile.OpenRead()))
{

}

回答by obelix

These come up time to time when I code as well. You could consider move the second using statement into another function?

当我编码时,这些也会不时出现。您可以考虑将第二个 using 语句移到另一个函数中吗?

回答by yoyoyoyosef

You could omit the brackets on all but the inner-most using:

除了最里面的括号外,您可以省略所有括号,使用:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
{
  while (!(outFile.EndOfStream || expFile.EndOfStream))
  {
    if (outFile.ReadLine() != expFile.ReadLine())
    {
      return false;
    }
  }
}

I think this is cleaner than putting several of the same type in the same using, as others have suggested, but I'm sure many people will think this is confusing

我认为这比像其他人建议的那样将几种相同类型的产品放在同一个使用中更干净,但我相信很多人会认为这令人困惑

回答by aquinas

You can also say:

你也可以说:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
{
   ...
}

But some people might find that hard to read. BTW, as an optimization to your problem, why dont you check that the file sizes are the same size first, before going line by line?

但有些人可能会觉得这很难阅读。顺便说一句,作为对您的问题的优化,为什么不先检查文件大小是否相同,然后再逐行进行?

回答by SLaks

Also, if you already know the paths, there's no point is scanning the directory.

此外,如果您已经知道路径,那么扫描目录是没有意义的。

Instead, I would recommend something like this:

相反,我会推荐这样的东西:

string directory = Path.Combine(Environment.CurrentDirectory, @"TestArea\");

using (StreamReader outFile = File.OpenText(directory + filename + ".out"))
using (StreamReader expFile = File.OpenText(directory + filename + ".exp"))) 
{
    //...

Path.Combinewill add a folder or filename to a path and make sure that there is exactly one backslash between the path and the name.

Path.Combine将文件夹或文件名添加到路径,并确保路径和名称之间正好有一个反斜杠。

File.OpenTextwill open a file and create a StreamReaderin one go.

File.OpenText将打开一个文件并StreamReader一次性创建一个。

By prefixing a string with @, you can avoid having to escape every backslash (eg, @"a\b\c")

通过在字符串前加上@,您可以避免转义每个反斜杠(例如,@"a\b\c"

回答by Jason Williams

If you want to compare the files efficiently, don't use StreamReaders at all, and then the usings aren't necessary - you can use low level stream reads to pull in buffers of data to compare.

如果您想有效地比较文件,根本不要使用 StreamReaders,然后就不需要使用了 - 您可以使用低级流读取来拉入数据缓冲区进行比较。

You can also compare things like the file size first to quickly detect different files to save yourself having to read all the data, too.

您还可以先比较文件大小等内容,以快速检测不同的文件,从而避免自己也必须阅读所有数据。