I think the code is doing exactly what it says; what's missing is a literal reading of it.
When you assign a new value to e.Cancel
, you are modifying the e
that is provided as a parameter to the function. After the event handler function finishes, this FormClosingEventArgs
instance, including any changes made to it from within the event handler, will be available to whatever code invoked the event handler. In this case, that's almost certainly the Winforms code written by Microsoft.
On the flip side, when you inside that event handler create a new instance of the type FormClosingEventArgs
and do something to it, there is nothing to provide that information back to the caller; you'd need something explicit for that. Since the caller is looking at the value of the parameter it passed in once the event handler completes, you'd need to somehow replace the content of e
as seen by the caller with the newly created instance. In other cases such a result might be provided as a return value.
In general, the result of new T()
, for some type T
, is an instance of type T
. You can thus work with the result of the expression new T()
as you would a non-null variable of type T
. In your particular case, you're assigning a value to a property on type T
(specifically, the instance of that type thus created). (There is the special case where the constructor fails, but let's not go there for now; for simple types, that would pretty much mean that you are in such dire straits that your program is unlikely to be able to continue running in any case.)
What's important here is that if you don't assign the result of the expression new T()
itself anywhere, the newly created instance is thrown away (technically, becomes inaccessible) once the statement completes. Then at some later point, the .NET garbage collector kicks in and actually reclaims the memory that was allocated. It isn't really any different from allocating a variable in one function, calling that function from another function and trying to access the variable thus allocated from the second function without doing anything to transfer the variable from the first function to the second, except here only one function is involved.
Doing something like your second line of code in the event handler would be rather unusual, but can in principle be valid if invoking the constructor has some side effect that you're looking to make use of, such as triggering lazy loading.