我如何知道使用“using”的最佳位置?
我对 C# 有点陌生,更习惯脚本语言。 我喜欢“使用”的想法,你实例化一个对象,然后只要你需要它,你就可以在它的范围内进行操作,然后当它完成它的目的时,让它自行处理。
但是,这对我来说并不自然。 当人们向我展示使用它的示例时,我认为它是完成工作的好工具,但我从未想过在自己的编程中使用它解决问题。
我如何识别使用 using
的好地方以及如何将它与 try-catch 块结合使用。 它们是否进入块内部,或者您通常希望将 using 语句包含在 try 块内?
I'm somewhat new to c#, more accustomed to scripting languages. I like the idea of 'using', you instantiate an object, and then you operate within its scope as long as you need it, then you let it dispose of itself when it's done its purpose.
But, it's not natural for me. When people show me examples using it, I recognize it as a good tool for the job, but it never occurs to me to solve problems with it in my own programming.
How can I recognize good places to use using
and how do I use it in conjunction with try-catch blocks. Do they go inside the block, or do you usually want to enclose a using statement within a try block?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
using
只能与实现IDisposable
的类型一起使用; 它保证即使发生错误也会调用Dispose()
方法。此代码:
相当于:
using
can only be used with types that implementIDisposable
; it guarantees that theDispose()
method will be called even if an error occurs.This code:
is equivalent to this:
我很少编写 try/catch 块 - 大多数异常都会被抛出到(接近)堆栈顶部。 如果我确实需要一个try/catch块,我不确定将其放在
using
语句内部与外部是否特别一致。 这实际上取决于您是否希望在运行异常处理代码之前或之后释放资源。如果您询问何时,您应该编写
using
语句 - 任何时候您“拥有”一个实现IDisposable
的对象(直接或间接通过继承)并控制其生命周期。 这通常是一个使用非托管资源(如文件句柄或网络连接)的对象。 它并不总是非常明显,但你可以通过经验来学习。 几乎任何与 IO 相关的东西都是一次性的,Windows 句柄(用于字体等)也类似。I rarely write try/catch blocks - most exceptions get thrown up to (near) the top of the stack. If I do need a try/catch block, I'm not sure I'm particularly consistent between putting it inside the
using
statement vs outside. It really depends on whether you want the resource to be disposed before of after your exception handling code is run.If you're asking about when you should be writing
using
statements - any time you "own" an object which implementsIDisposable
(either directly or indirectly through inheritance) and control its lifetime. That's usually an object which uses an unmanaged resource like a file handle or network connection. It's not always hugely obvious, but you learn through experience. Almost anything to do with IO will be disposable, and Windows handles (for fonts etc) are similar.我过去常常将其视为“每次类型实现 IDisposable 时都使用它,并且您将不再需要此特定实例”。
I use to think of it as "Use it every time when type implements IDisposable and you you're not goinng to need this particular instance any more".
如果您想知道如何在您自己的设计中创造性地使用它,请查看您自己的一些代码,以了解在退出封闭块之前绝对必须执行特定代码位的情况。 在这些情况下,
try
/finally
或using
可以为您提供帮助。特别是,如果您尝试通过捕获所有异常来实现此目的,那么您确实必须更改为
try
/finally
或using
。如果该模式出现多次,您可以创建一个实现 IDisposable 的类来捕获该模式,并允许您使用 using 语句调用该模式。 但如果您遇到的特定情况似乎是一次性的,那么只需使用
try
/finally
即可。两者非常相似,实际上 -
using
是根据try
/finally
指定的,但即使我们只有using< /code>,我们可以自己构建
try
/finally
:现在你可以说:
这与以下内容相同:
只需将其视为执行某些代码的一种方法离开范围后。
If you want to know how to creatively use it within your own designs, look through some of your own code for situations where a particular bit of code absolutely must execute before the enclosing block is exited. These are the situations where
try
/finally
orusing
can help you.In particular, if you've tried to achieve this by catching all exceptions, then you really must change to
try
/finally
orusing
instead.If the pattern occurs several times, you could create a class that implements
IDisposable
in order to capture the pattern, and allowing you to invoke the pattern with theusing
statement. But if you have a specific case that appears to be a one-off, then just usetry
/finally
.The two are very similar, really -
using
is specified in terms oftry
/finally
, but even if we only hadusing
, we could buildtry
/finally
ourselves:Now you could say:
Which is the same as:
Just think of it as a way to get some code to execute upon leaving a scope.
Mitch 说的是,另外..
您可以在 try..catch 块外部或内部使用 using 语句,这实际上取决于您想要实现的目标,即您是否合理地期望在使用您所使用的特定对象时抛出异常。例如,计划从中恢复。
出于同样的原因,如果需要,您还可以在finally 块中释放一个实现IDisposable 的对象。
WHat Mitch said, plus..
You can use the using statement outside or inside a try..catch block it really would depend on what you are trying to achieve i.e. whether you reasonably expect something to throw an exception whilst using a particular object which you plan to recover from, for example.
By the same token, you could also Dispose of an object which implements IDisposable in a finally block if you needed to.
您可以将 using 包含在 try/catch 块内,也可以将 try/catch 块包含在 using 内。
using 很好的一种情况是当您使用 DBConnection 和 DBCommands 执行数据库操作时:
现在,当您离开 using 块时,您的命令将被释放并关闭连接。
You can enclose a using inside a try/catch block and you can enclose a try/catch block inside a using.
One situation where using is nice is when you are doing database operations using DBConnection and DBCommands:
Now when you leave the using blocks your command is disposed and the connection is closed.
米奇说的是对的。 因此,using 的主要用途是确保 IDisposable 对象得到处置,不必编写 try/catch 或 try/finally 语句。
现在,您可能也会对更高级的用途感兴趣。 当您使用 using 语句时,编译器会生成一个 try/finally,并且还会在它生成的 finally 内部为您生成对 Dispose() 的调用。 您可以使用此 Dispose() 方法作为“钩子”来执行您想要的任何操作...不必与释放资源相关。
例如,Jeffrey Richter 在他编写的计时器对象中使用了它。 你可以用它做这样的事情(仅概念性的):
What Mitch said is right. So the main use of using is to ensure that IDisposable objects get disposed of, without having to code a try/catch or try/finally statement.
Now, there's a more advanced use you might find interesting as well. When you use a using statement, the compiler generates a try/finally, and it also generates a call to Dispose() for you inside of the finally that it generates. You can use this Dispose() method as a "hook" to do anything you want ... doesn't have to be related to releasing resources.
For example, Jeffrey Richter uses this in a timer object he wrote. You can do something like this with it (conceptual only):
如果一个类实现了 IDisposable,这可能是有充分理由的。 因此,任何实现 IDisposable 的类都应该被释放。
If a class implements IDisposable, it's probably for good reason. So any class that implements IDisposable should be disposed.
鉴于它就是所谓的“语法糖”,并且将生成与 try/finally dispose 构造相同的 IL,它实际上只是“简化”此类代码的一种好方法。
我喜欢用它来简化大量使用一次性对象的代码部分,即访问文件和图形对象等资源,并且我想确保我不会忘记处理资源对象的处置。
Given that it is what is known as "syntactic sugar" and will produce the same IL as a try/finally dispose construct, it is really just a nice way of "short-handing" such code.
I like to use it to simplify sections of code where disposable objects are used a lot i.e. access to resources such as files and graphics objects and I want to make sure that I don't forget to handle the disposing of the resource object.
当您需要确定性对象处置时,请使用using。 例如,如果您打开一个文件,该文件将被锁定。 您通常会希望尽快关闭该文件,以便其他程序可以访问它。 如果你不使用 using 并写成这样:
并且在“do smth”期间发生异常,你不知道对文件操作的对象何时实际被释放并且文件被关闭。 使用using,您可以确定一旦离开using语句块 - 无论是直接还是通过异常,usinging语句中的对象都是通过调用 IDisposable::Dispose 进行处置:
Use using when you need deterministic object disposal. For example, if you open a file, the file is locked. You will often want the file to be closed as soon as possible so that other programs could access it. If you don't use using and write smth like:
and an exception occurs during "do smth" you don't know when the objects operating on a file are actually disposed and file is closed. With using you know for sure that once you've left the using statement block - either directly or via exception the object in the useing statement is disposed by calling IDisposable::Dispose:
我注意到,当已知 Dispose 方法确实会引起注意时,程序员就不会费心调用它,因为它似乎毫无意义。 但是,如果该对象实现了 IDisposable (希望)是有原因的,并且该对象的未来版本实际上可能在 Dispose 方法中包含代码 - 因此请始终调用它。
I've noticed that when the Dispose method is known to do notice, so programmers don't bother calling it as it seems pointless. However, if the object implements IDisposable it's (hopefully) for a reason and future versions of that object may actually have code in the Dispose method - so always call it.