If I have this method:
开发者_如何学编程public StreamReader GetResourceStream(string filename)
{
using (Stream stream = this.GetType().Assembly.GetManifestResourceStream(filename))
using (StreamReader sr = new StreamReader(stream))
{
return sr;
}
}
When I call it, should I call it this way
StreamReader resource = GetResourceStream("blah.xml");
or this way:
using (StreamReader resource = GetResourceStream("blah.xml"))
{
// Do stuff
}
If second way, does this means the using (StreamReader sr = new StreamReader(stream))
line is not making any difference by using a using
statement?
You should change the method itself not to include a using
statement, but then make sure that the calling code uses a using
statement:
public StreamReader GetResourceStream(string filename)
{
return new StreamReader(GetType().Assembly
.GetManifestResourceStream(filename));
}
using (StreamReader resource = GetResourceStream("blah.xml"))
{
// Do stuff
}
That way it will only dispose of the resource when you've actually used it. Basically the method is giving ownership of the returned resource to the caller. That much isn't too bad - it's reasonably common, even (think of File.OpenText
etc).
Where it gets more tricky is when you pass a resource into a method or constructor - should the "called" code take ownership or not? Usually not, but occasionally it's appropriate - for example, the Bitmap(Stream)
documentation states that you must keep the stream alive for as long as the bitmap is required. In fact, disposing of the bitmap also disposes of the stream, so you still only have one resource to keep track of... but you do need to know that you mustn't close the stream.
It doesn't really make sense to have the GetResourceStream
method put the using statement around the object it's returning. That means you will be returning an object in a disposed state, and what good is that? It will throw ObjectDisposed
exceptions at you.
So remove the using
statements inside your factory method, and apply the using
statement where you're actually using it.
It should look more like this:
public StreamReader GetResourceStream(string filename)
{
Stream stream = this.GetType().Assembly.GetManifestResourceStream(filename);
return new StreamReader(stream)
}
When program flow exits the second using block, sr.Dispose() will be called, disposing the StreamReader and making it useless.
You need to make use of sr before flow control exits that block.
精彩评论