在 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
Nested using statements in C#
提问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 using
statements.
嵌套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 using
statement, 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. using
is 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 IDisposable
s are of the same type, you can do the following:
当IDisposable
s 的类型相同时,您可以执行以下操作:
using (StreamReader outFile = new StreamReader(outputFile.OpenRead()),
expFile = new StreamReader(expectedFile.OpenRead()) {
// ...
}
The MSDN page on using
has documentation on this language feature.
MSDN 页面上using
有关于此语言功能的文档。
You can do the following whether or not the IDisposable
s are of the same type:
无论IDisposable
s 是否属于同一类型,您都可以执行以下操作:
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.Combine
will 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.OpenText
will open a file and create a StreamReader
in 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.
您还可以先比较文件大小等内容,以快速检测不同的文件,从而避免自己也必须阅读所有数据。