可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Both classes for practicality sake are disposable.
I understand what a using block does. But I'm not sure of all of the ways it can or needs to be used.
For example is this correct?
using (MyClass myClass = new MyClass(params))
{
myClass.name = "Steve";
SecondClass myClassSecond = new SecondClass(params);
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
Are both classes above disposed of?
Or do I need both inside a using statement?
using (MyClass myClass = new MyClass(params))
{
myClass.name = "Steve";
using (SecondClass myClassSecond = new SecondClass(params))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
}
Is the above correct, or is there a better way to use multiple using statements?
回答1:
- The
using
statement allows the programmer to specify when objects that use resources should release them.
- The object provided to the using statement must implement the
IDisposable
interface.
- This interface provides the
Dispose
method, which should release the object's resources.
Here is the sample showing use of using statement:
using System;
//Object of this class will be given to using hence IDisposable
class C : IDisposable
{
public void UseLimitedResource()
{
Console.WriteLine("Using limited resource...");
}
//Dispose() Method
void IDisposable.Dispose()
{
Console.WriteLine("Disposing limited resource.");
}
}
class Program
{
static void Main()
{
using (C c = new C()) //Object of Class defined above
{
c.UseLimitedResource();
//Object automatically disposed before closing.
}
Console.WriteLine("Now outside using statement.");
Console.ReadLine();
}
}
A using statement can be exited either when:
- the end of the
using
statement is reached or
- if an exception is thrown and control leaves the statement block before the end of the statement.
Which is proper method?
As you are saying that
Both classes for practicality sake are disposable
., then your second approach is the appropriate one. that is:
using (MyClass myClass = new MyClass(params))
{
myClass.name = "Steve";
using (SecondClass myClassSecond = new SecondClass(params))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
}
回答2:
Using blocks are handy when you are working with anything that implements IDisposable
interface. MSDN:
[using Statement] Defines a scope, outside of which an object or objects will be disposed.
So, these is effectively an equivalent of
IDisposable resource = new Whatever();
try {
// whatever
}
finally {
resource.Dispose();
}
The primary advantages of using
are: it automatically disposes the object upon leaving the using
block, so (1) you won't forget to do it and (2) it does the cleanup in case of exception.
Short rules:
- Anytime you open a file/database connection or create an instance of class that needs any kind of cleanup - do it in
using
block.
- If the lifetime of the object should extend the method scope - wrap it in a class, implement
IDisposable
in that class, instantiate a resource in constructor, cleanup in Dispose
.
回答3:
Your second example is proper assuming SecondClass is indeed dispoable. If it is the first example is not correct as mySecondClass will not be disposed of. If a block of code controls the lifetime of a disposable instance it should always dispose of it.
FYI I prefer this style for disposing multiple objects in the same block as I find it more readable.
using (MyClass myClass = new MyClass(params))
using (SecondClass myClassSecond = new SecondClass(params))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
Both usings
share the same scope and Dispose in reverse order of declaration.
回答4:
A using block does not automatically dispose any child objects that implement IDisposable
. You have to wrap inner disposables in using blocks if you want them disposed. You do, however, have a few different options for this.
You could nest multiple using blocks and they are evaluated inner-most to outer-most. There is a better way to do this, but the following example works:
using (MyClass myClass = new MyClass(parameters))
{
using (SecondClass myClassSecond = new SecondClass(parameters))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
}
If the declarations are consecutive and you don't need to do anything in between, the following syntax is more succinct:
using (MyClass myClass = new MyClass(parameters))
using (SecondClass myClassSecond = new SecondClass(parameters))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
If you need to do something in between the declarations, then your latter example is correct:
using (MyClass myClass = new MyClass(parameters))
{
myClass.name = "Steve";
using (SecondClass myClassSecond = new SecondClass(parameters))
{
myClassSecond.name = "George";
myClassSecond.msg = "Hello Man in the Yellow Hat";
}
}
回答5:
My rule of thumb is...if it implements idisposable, I use a using block.
Always better safe than sorry.
To answer your question, I would go with the second option.
回答6:
The simple answer is if the class has a dispose method, use using.
http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx
If it does not, no need.
http://msdn.microsoft.com/en-us/library/system.random.aspx
I've always wished this was more in your face in the MSDN documentation. At the end of the day, it's the classes that implement IDisposable, but really what I want is some sort of giant icon on the page that in some way says. 'Pay attention dummy! You must manage this yourself!'
回答7:
The using
block is purely a syntactically simple way of dealing with IDisposable objects. If you understand what using
does, then you should understand how it can and should be used.
See this question for exactly what the using
block is translated into:
Uses of "using" in C#
回答8:
That depends on what those classes are and how they dispose of any resources they use. The using
statement is essentially the same thing as a try/finally
block (no catch
) which disposes of its resources in the finally
block (by calling .Dispose()
on the object in question).
So, first of all, if the class in question doesn't implement IDisposable
then it's a moot point, you can't use it in a using
block in that case. If it does implement IDisposable
then chances are it does so for a reason and .Dispose()
should be called on that object when you're done with it. In those cases, it's prudent to wrap it in a using
block to guarantee the disposal. (Well, "guarantee" in so much as the finally
block will be executed. Which is usually the case, unless something much worse has happened.)
回答9:
I like to implement IDisposable
in the classes I create if they use lots of resources or if I create it as a wrapper for file handling or network resources.
In class objects that I use, I think it is important to call with a using
block if the object in question opens files, creates network connections, etc.
Some developers will write a class that implements IDisposable
just so they can put their code in the cleaner looking using
block, but I think this abuses the reason for creating something that is Disposable.