Yes Dispose() would be called in both examples. They are functionally equivalent except that in the second example the disposed StreamReader would still be in scope. Therefore the first method is preferred, as using a disposed object is usually a Bad Idea However as others have pointed out, it is sometimes OK to use a disposed object.In such cases you might want to use your second example.
But you have to know what you're doing and I would avoid it if at all possible.
Yes, Dispose() would be called in both examples. They are functionally equivalent except that in the second example the disposed StreamReader would still be in scope. Therefore the first method is preferred, as using a disposed object is usually a Bad Idea.
However as others have pointed out, it is sometimes OK to use a disposed object. In such cases you might want to use your second example. But you have to know what you're doing and I would avoid it if at all possible.
2 the first form is preferred, as to avoid polluting the scope of the enclosing function with sr2, which after the using construct points to a disposed object. – Marco Oct 15 '10 at 17:56 @Macro - Excellent point. I updated accordingly.
– Greg Oct 15 '10 at 17:59 Thanks for all the good answers. – thd Oct 15 '10 at 18:07.
Yes, absolutely. The details are in section 8.13. There isn't a concise statement of your exact question, but: A using statement of the form using (expression) statement has the same three possible expansions, but in this case ResourceType is implicitly the compile-time type of the expression, and the resource variable is inaccessible in, and invisible to, the embedded statement.
The "three possible expansions" referred to cover the more common case of declaring a variable at the same time. Basically the important thing is that it behaves the same way, aside from the variable's scope. Dispose will still be called - otherwise there'd be no point in putting in a using statement at all :) Note that the two aren't quite equivalent in terms of what's valid within the block, because a variable declared by the using statement is readonly.So this is valid: // Warning but no error MemoryStream ms = new MemoryStream(); using (ms) { ms = null; } but this isn't: using (MemoryStream ms = new MemoryStream()) { // error CS1656: Cannot assign to 'ms' because it is a 'using variable' ms = null; } Note that even in the case where it's valid, it's the original value of ms which is used for disposal.
The compiler makes this clear: warning CS0728: Possibly incorrect assignment to local 'ms' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local. Note that this form doesn't generate a warning: // No warning MemoryStream ms; using (ms = new MemoryStream()) { ms = null; } On the other hand, aside from that, they really will behave in the same way.
EDIT: As bzlm notes, the fact that the variable remains in scope after the using statement means it's usually not a good idea. However, objects which have been disposed aren't always unusable. For example: MemoryStream ms = new MemoryStream(); using (ms) { // Do stuff } byte data = ms.ToArray(); That will work just fine - the MemoryStream keeps the data even when it's disposed.
It still feels somewhat wrong to me though.
1 "You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources" seems relevant here too. – bzlm Oct 15 '10 at 17:57 Thanks Jon.
I hadn't seen this covered in this depth of scope before. – jcolebrand Oct 15 '10 at 18:03.
Both codes are pretty much the same. Dispose will be called once control leaves the using block. If the exception occurs before then it won't be called in either case.
But apart from asynchronous exceptions this won't happen in your code. stackoverflow.com/questions/3923457/is-c... Is a similar discussion focusing on the interaction with thread abortion.
Using takes an object that implements IDisposable. How and where that object is created is not taken into account, when the compiler generates the code to call Dispose at the end for the using block.
Good question. I would say yes, because the using code block is little more than syntax sugar for the following: try { var myObj = } finally { myObj.Dispose(); } Notice that, when substituted for your using block, the variable you end up disposing has another handle that is visible outside the code block (sr2). This reference will prevent the instance from being garbage-collected after the using statement, but since it's been disposed, unless it's smart enough to recover from a mid-scope Dispose(), it's not going to be of much use.
The myObj variable declaration would be outside the try block, otherwise it's not visible in the finally block. – Greg Oct 15 '10 at 18:20.
MSDN says not entirely equal regarding exceptions during initialization. Also consider the following scoping scenario: //Sample 1 using (StreamReader sr1 = new StreamReader(@"C:\Data. Txt")) { string s1 = sr1.ReadToEnd(); //Do something with s1... } sr1.ReadToEnd() // sr1 not in scope.
Does not compile, but //Sample 2 StreamReader sr2 = new StreamReader(@"C:\Data. Txt"); using (sr2) { string s2 = sr2.ReadToEnd(); //Do something with s2... } sr2.ReadToEnd() // possible to write, but accessing a disposed object. Compiles but access a disposed object.
However, objects which have been disposed aren't always unusable. That will work just fine - the MemoryStream keeps the data even when it's disposed. It still feels somewhat wrong to me though.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.