Skip to content

Inconsistencies with null-coalescing wrapping on method chains #1573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
SigtryggurO opened this issue Apr 14, 2025 · 0 comments
Open

Inconsistencies with null-coalescing wrapping on method chains #1573

SigtryggurO opened this issue Apr 14, 2025 · 0 comments
Milestone

Comments

@SigtryggurO
Copy link

SigtryggurO commented Apr 14, 2025

csharpier 0.30.6

Input:

var test4 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(cancellationToken) ?? throw new Exception("This is an exception message");

Output:

var test4 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(cancellationToken) ?? throw new Exception("This is an exception message");

Expected behavior:

var test4 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(cancellationToken)
    ?? throw new Exception("This is an exception message");

On its own, this might seem fine, but when compared to a similar method where we modify different parts of the assignment, the inconsistency becomes apparent:

// Fully inline: short method chain and short exception message.
var test1 = await context.Images.FirstAsync(cancellationToken) ?? throw new Exception("This is an exception message");

// Break after '=', everything else fits on one line.
var test2_1 =
    await context.Images.FirstOrDefaultAsync(cancellationToken) ?? throw new Exception("This is an exception message");

// Similar to test2_1, slightly longer exception message but still contained in a single line.
var test2_2 =
    await context.Images.FirstAsync(cancellationToken) ?? throw new Exception("This is a little longer exception message");

// Breaks after '=', and '??' is on a new line due to method length.
var test3_1 =
    await context.Images.FirstOrDefaultAsync(x => x.Id == ImageId.CreateUnique(), cancellationToken)
    ?? throw new Exception("This is an exception message");

// Similar to test3_1, but it wraps due to message length.
var test3_2 =
    await context.Images.FirstAsync(cancellationToken)
    ?? throw new Exception("This is a much longer exception message which should be long enough to wrap on its own");

// Multiline formatting: Last part of method chain is short and the exception message is short, so '??' is not wrapped, inconsistent with others.
var test4 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(cancellationToken) ?? throw new Exception("This is an exception message");

// Multiline formatting: Last part of method chain is long, so '??' is wrapped.
var test5_1 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(x => x.Id == ImageId.CreateUnique(), cancellationToken)
    ?? throw new Exception("This is an exception message");

// Multiline formatting: Exception message is long, so '??' is wrapped.
var test5_2 =
    await context
        .Images.Where(x => x.Id == ImageId.CreateUnique() && x.Created == DateTime.MaxValue)
        .FirstOrDefaultAsync(cancellationToken)
    ?? throw new Exception("This is a much longer exception message which should be long enough to wrap on its own");

I also tried without assignment and swapped out throw for a static function with same results.

@belav belav added this to the 1.1.0 milestone Apr 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants