Is it possible to clear an external variable inside a block?

I have a static StreamWriter field for a log file with which I need to access through a lambda function that listens for StandardOutput during a lengthy process.

I use the null / not-null field status to determine if a process is busy in another thread; actions must be performed sequentially.

My question is: what happens when I set a null variable inside a usage block? Will it still fit correctly?

public class Service { private static StreamWriter logger; void Run(string logFile) { using (logger = new StreamWriter(logFile)) { /* ... */ logger = null; } } } 
+4
source share
3 answers

According to C # link, & sect; 8.13, your code:

 private static StreamWriter logger; using (logger = new StreamWriter(logFile)) { /* ... */ logger = null; } 

equivalently

 private static StreamWriter logger; { // using scope logger = new StreamWriter(logFile); IDisposable resource = logger; // hidden var inserted by the compiler try { /* ... */ logger = null; } finally { if (resource != null) resource.Dispose(); } } 

Relevant quote:

A using a view instruction

  using (expression) statement 

has the same three possible extensions, but in this case ResourceType is implicitly a type of compilation time of the expression, and the resource variable is inaccessible and invisible to the built-in operator.

+3
source

My question is: what happens when I set a null variable inside a usage block? Will it still fit correctly?

It depends on where your variable is declared. It will either be disposed of correctly or your code will not compile in the first place.

If your variable is declared outside the using statement: Yes

 A a; using (a = new A()) { a = null; } 

Yes, it will be installed correctly. For a simple test:

A variable is nulled within a using block and disposed of successfully
My color scheme is Ragnarok Gray text.

Even when the job is released, the link to new A() seems to be preserved. a is deleted at the end of the using statement, as expected, even if it was muffled internally.

In some versions of Visual Studio, this may result in Compiler Warning (level 2) CS0728 :

Possibly incorrect assignment to local "a", which is an argument for the use or lock statement. A call to Dispose or unlock will occur at the original local value.

If your variable is declared in a using: N / A statement

 using (var a = new A()) { a = null; } 

The above code will not compile. First of all, you are not allowed to assign a using variable. The above code creates this compilation error:

Cannot assign 'a' because it is 'using variable'

This is CS1656 Compiler Error .

This error occurs when a variable assignment occurs in a read-only context. Read-only contexts include foreach iteration variables using variables and fixed variables. To resolve this error, avoid operator variable assignments using blocks, foreach, and fixed statements.

+2
source

It's not a problem. You need to look at IL using ildasm.exe to see how the compiler does it. But it generates an extra variable to hold the reference to the object, so you cannot shoot that leg like that. The equivalent C # code will (approximately) look like this:

 StreamWriter $temp = new StreamWriter(logFile); logger = $temp; try { // etc... logger = null; } finally { if ($temp != null) $temp.Dispose(); } 

This extra temp variable saves you the trouble.

+2
source

Source: https://habr.com/ru/post/1479638/


All Articles