Search code examples
c#nullable-reference-types

How can I tell C# that I am initializing the member variables?


In the below code I am initializing all my non-nullable member variables. But C# does not recognize it. Is there a way to avoid the warnings other than using

_elevatorPitch = default!;

or

#pragma warning disable CS8618 

I like to make use of the warnings and having it ignore it for specific cases means I won't get a warning for cases where I am not initializing as I should.

But in this case, everything is being initialized.

public CreateAppointmentDto(Event src, AppUser user, IBlobService blobService,
    IDocumentService documentService, IHttpClientFactory httpClientFactory, IEnumerable<Interest> allInterests)
{

    AllInterests = allInterests;

    ApplyFromEvent(src, user, blobService);
}

public void ApplyFromEvent(Event src, AppUser user, IBlobService blobService)
{

    ArgumentNullException.ThrowIfNull(src.Owner);
    ArgumentNullException.ThrowIfNull(src.Parent);
    ArgumentNullException.ThrowIfNull(src.Signups);
    if (src.AppointmentType == ExAppointmentType.OccurrenceInstance)
        throw new ArgumentException("Cannot edit an appointment that is an occurrence instance.");

    Event = src;
    Type = src.Type;
    _subject = src.Subject;
    _elevatorPitch = src.ElevatorPitch ?? string.Empty;
    HasAddress = src.HasAddress;
    AddressModel = new AddressFormPageModel(src.Address);
    Workplace = src.Workplace;
    Priority = src.Priority;
    MaxSignups = src.MaxSignups;
    Enabled = src.Enabled;
    Private = src.Private;

    Owner = src.Owner;
    ParentId = src.Parent.Id;
    Interest = src.Interest;
    Tags = src.Tags ?? new List<Tag>();

    // bugbug DescriptionRichText!.RichText = src.Description;
    Thumbnail = new FileUploadModel(blobService, src.Thumbnail, SystemBlobs.EventUploadThumbnail);
    Picture = new FileUploadModel(blobService, src.Picture, SystemBlobs.EventUploadPicture);

    StartDateTime = src.StartDateTime.DateTime;
    EndDateTime = src.EndDateTime.DateTime;
    TimeZoneId = src.StartDateTime.TimeZoneId;

    var signup = src.Signups.FirstOrDefault(s => s.User.Id == user.Id);
    StatusId = (int)(signup?.Commitment ?? Signup.Mode.Unknown);

    AppointmentType = (AppointmentType)(int)src.AppointmentType;
    AllDay = src.ApptAllDay;
    RecurrenceInfo = src.RecurrenceInfo;
    Shifts = src.ApptShifts != null ? ShiftItemModel.FromShiftList(src.ApptShifts) : new List<ShiftItemModel>();
}

And here's the warnings:

2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable field '_subject' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable field '_elevatorPitch' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'TimeZoneId' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'AddressModel' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'Tags' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'Thumbnail' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'Picture' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
2>C:\Git\LouisHowe\LouisHowe.web\PageModels\EventJob\CreateAppointmentDto.cs(276,10,276,30): warning CS8618: Non-nullable property 'Shifts' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Solution

  • You can apply the MemberNotNull attribute to ApplyFromEvent to tell the compiler that the specified member is not null when the method returns:

    [MemberNotNull(nameof(_subject)), MemberNotNull(nameof(_elevatorPitch)), /* etc. */]
    public void ApplyFromEvent(Event src, AppUser user, IBlobService blobService)
    {
        // ...
    }
    

    This is a bit verbose, though, because you'll have to say it for every member.