Skip to content

Conversation

CyrusNajmabadi
Copy link
Member

Specifically, if you write:

if (x != null)
{
    x.SomeMethod(); // like 'Dispose'
    x = null;
}

Then this is fine to translate to:

x?.SomeMethod();
x = null;

This is a somewhat common pattern we see in cleanup methods (like Dispose) where an operation is done on a field if it is non-null, and then it is null'ed out.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner June 16, 2025 20:58
@CyrusNajmabadi CyrusNajmabadi requested a review from akhera99 June 16, 2025 20:58

// we have `if (x != null) x.Y();`. Update `x.Y()` to be `x?.Y()`, then replace the entire
// if-statement with that expression statement.
var newWhenTrueStatement = CreateConditionalAccessExpression(
syntaxFacts, generator, whenPartIsNullable, whenTrueStatement, match);
Contract.ThrowIfNull(newWhenTrueStatement);

var isElseIf = syntaxFacts.IsElseClause(ifStatement.Parent);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i reordered thids pretty heavily. it had this local variable to indicate if we are in the else if (x != null) x.Foo() case. And then lots of contorted logic doing work, but throwing in random checks of this local value. So i just split things into an if/else where we keep all the logic for this case in one place, and then handle the normal if case below that.


Protected Overrides Function ReplaceBlockStatements(block As ExecutableStatementSyntax, newInnerStatement As ExecutableStatementSyntax) As ExecutableStatementSyntax
Throw ExceptionUtilities.Unreachable()
End Function
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed for VB. we now just call into C# to handle the entire case of else if, which means it can just inline the tryGetBlock and replaceblockstatements within PostProcessElseIf. VB has no need for it as PostProcessElseIf is never called for it.

// `if (<expr> != null) { <expr>.Method(); <expr> = null; }`
//
// If 'expr' is not null, then we execute the body and then end up with expr being null. So `expr?.Method(); expr = null;`
// preserves those semantics. Simialrly, if is expr is null, then `expr?.Method();` does nothing, and `expr = null` keeps it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// preserves those semantics. Simialrly, if is expr is null, then `expr?.Method();` does nothing, and `expr = null` keeps it
// preserves those semantics. Similarly, if is expr is null, then `expr?.Method();` does nothing, and `expr = null` keeps it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants