What is the difference between
S instance = new S();
instance.s = "foo";
and
S instance;
instance.s = "foo";
?
As Marc correctly points out, both are equally bad; the right thing to do is to make an immutable struct that takes the string in its constructor.
And as Marc correctly points out, functionally there is no difference.
However, that does not answer the question that you actually asked, which is "what happens behind the scenes?" By "behind the scenes" I'm assuming that you're talking about the compiler's semantic analysis of the code, as described in the C# specification.
Fortunately the specification is extremely clear on the difference between these two cases.
First off, as you correctly note, in the first case the variable is considered to be definitely assigned after the first statement. In the second case the variable is not considered to be definitely assigned until after the second statement.
However, the definite assignment analysis is simply a consequence of the actual meaning of the code, which is as follows.
The first fragment:
- allocates storage for
instance
- allocates temporary storage for the temporary value
- initializes the temporary value to the default struct state
- copies the bits of the temporary value to the storage for
instance
- now
instance
is definitely assigned because all its bits were copied from another value
- copies the string reference into the storage for
instance
The second fragment
- allocates storage for
instance
- copies the string reference into the storage for
instance
- now
instance
is definitely assigned because all its fields have been assigned
The compiler is permitted to notice that there is no way to determine whether or not a temporary was created, initialized and copied. If it does determine that then it is permitted to elide the creation of the temporary, and generate the same code for both fragments. The compiler is not required to do so; this is an optimization and optimizations are never required.
Now, you might wonder under what circumstances you can determine that a temporary was created, initialized and copied. If you do wonder that then read my article on the subject:
https://ericlippert.com/2010/10/11/debunking-another-myth-about-value-types/