Skip to content

Commit d9ff464

Browse files
committed
Merge branch 'maintenance/CS8618' into develop
The Roslyn code analyzers will throw a `CS8616` if a non-nullable property will not be initialized after the constructor has executed. This is a problem for models that are expected to be initialized by e.g. data binding, mapping, or deserialization. We used to work around this using the `[NotNull, DisallowNull]` attributes on a nullable property, which I liked as it was explicit about what it was doing. Unfortunately, as of .NET 5.0.4 (SDK 5.0.201), that now throws a `CS8616` as well. Given that, we need to instead use the less obvious null-forgiving operator instead with these cases. Given this, I've replaced the cases where we were using `[NotNull, DisallowNull]` with `= default!;` on a non-nullable type instead.
2 parents b7ecaac + 60b83cb commit d9ff464

6 files changed

Lines changed: 32 additions & 56 deletions

File tree

OnTopic.Tests/BindingModels/BasicTopicBindingModel.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
using System.Diagnostics.CodeAnalysis;
88
using OnTopic.Models;
99

10-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
11-
1210
namespace OnTopic.Tests.BindingModels {
1311

1412
/*============================================================================================================================
@@ -29,13 +27,11 @@ public BasicTopicBindingModel(string key, string contentType) {
2927
ContentType = contentType;
3028
}
3129

32-
[Required, NotNull, DisallowNull]
33-
public string? Key { get; init; }
30+
[Required]
31+
public string Key { get; init; } = default!;
3432

35-
[Required, NotNull, DisallowNull]
36-
public string? ContentType { get; init; }
33+
[Required]
34+
public string ContentType { get; init; } = default!;
3735

3836
} //Class
39-
} //Namespace
40-
41-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
37+
} //Namespace

OnTopic.Tests/BindingModels/RecordTopicBindingModel.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
using System.Diagnostics.CodeAnalysis;
88
using OnTopic.Models;
99

10-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
11-
1210
namespace OnTopic.Tests.BindingModels {
1311

1412
/*============================================================================================================================
@@ -25,13 +23,11 @@ public class RecordTopicBindingModel : ITopicBindingModel {
2523

2624
public RecordTopicBindingModel() { }
2725

28-
[Required, NotNull, DisallowNull]
29-
public string? Key { get; init; }
26+
[Required]
27+
public string Key { get; init; } = default!;
3028

31-
[Required, NotNull, DisallowNull]
32-
public string? ContentType { get; init; }
29+
[Required]
30+
public string ContentType { get; init; } = default!;
3331

3432
} //Class
35-
} //Namespace
36-
37-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
33+
} //Namespace

OnTopic.ViewModels/BindingModels/AssociatedTopicBindingModel.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
using OnTopic.Mapping.Reverse;
99
using OnTopic.Models;
1010

11-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
12-
1311
namespace OnTopic.ViewModels.BindingModels {
1412

1513
/*============================================================================================================================
@@ -35,10 +33,8 @@ public record AssociatedTopicBindingModel : IAssociatedTopicBindingModel {
3533
/// <requires description="The value from the getter must not be null." exception="T:System.ArgumentNullException">
3634
/// value is not null
3735
/// </requires>
38-
[Required, NotNull, DisallowNull]
39-
public string? UniqueKey { get; init; }
36+
[Required]
37+
public string UniqueKey { get; init; } = default!;
4038

4139
} //Class
42-
} //Namespaces
43-
44-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
40+
} //Namespace

OnTopic.ViewModels/NavigationTopicViewModel.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
using System.Diagnostics.CodeAnalysis;
1010
using OnTopic.Models;
1111

12-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
13-
1412
namespace OnTopic.ViewModels {
1513

1614
/*============================================================================================================================
@@ -38,8 +36,8 @@ public sealed record NavigationTopicViewModel : INavigationTopicViewModel<Naviga
3836
| TITLE
3937
\-------------------------------------------------------------------------------------------------------------------------*/
4038
/// <inheritdoc cref="TopicViewModel"/>
41-
[Required, NotNull, DisallowNull]
42-
public string? Title { get; init; }
39+
[Required]
40+
public string Title { get; init; } = default!;
4341

4442
/*==========================================================================================================================
4543
| SHORT TITLE
@@ -53,8 +51,8 @@ public sealed record NavigationTopicViewModel : INavigationTopicViewModel<Naviga
5351
| WEB PATH
5452
\-------------------------------------------------------------------------------------------------------------------------*/
5553
/// <inheritdoc cref="WebPath"/>
56-
[Required, NotNull, DisallowNull]
57-
public string? WebPath { get; init; }
54+
[Required]
55+
public string WebPath { get; init; } = default!;
5856

5957
/*==========================================================================================================================
6058
| CHILDREN
@@ -75,6 +73,4 @@ public bool IsSelected(string webPath) =>
7573
$"{webPath}/".StartsWith($"{WebPath}", StringComparison.OrdinalIgnoreCase);
7674

7775
} //Class
78-
} //Namespace
79-
80-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
76+
} //Namespace

OnTopic.ViewModels/TopicViewModel.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
using OnTopic.Mapping.Annotations;
1010
using OnTopic.Models;
1111

12-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
13-
1412
namespace OnTopic.ViewModels {
1513

1614
/*============================================================================================================================
@@ -36,29 +34,29 @@ public record TopicViewModel: ITopicViewModel, ICoreTopicViewModel, IAssociatedT
3634
| KEY
3735
\-------------------------------------------------------------------------------------------------------------------------*/
3836
/// <inheritdoc />
39-
[Required, NotNull, DisallowNull]
40-
public string? Key { get; init; }
37+
[Required]
38+
public string Key { get; init; } = default!;
4139

4240
/*==========================================================================================================================
4341
| CONTENT TYPE
4442
\-------------------------------------------------------------------------------------------------------------------------*/
4543
/// <inheritdoc />
46-
[Required, NotNull, DisallowNull]
47-
public string? ContentType { get; init; }
44+
[Required]
45+
public string ContentType { get; init; } = default!;
4846

4947
/*==========================================================================================================================
5048
| UNIQUE KEY
5149
\-------------------------------------------------------------------------------------------------------------------------*/
5250
/// <inheritdoc />
53-
[Required, NotNull, DisallowNull]
54-
public string? UniqueKey { get; init; }
51+
[Required]
52+
public string UniqueKey { get; init; } = default!;
5553

5654
/*==========================================================================================================================
5755
| WEB PATH
5856
\-------------------------------------------------------------------------------------------------------------------------*/
5957
/// <inheritdoc />
60-
[Required, NotNull, DisallowNull]
61-
public string? WebPath { get; init; }
58+
[Required]
59+
public string WebPath { get; init; } = default!;
6260

6361
/*==========================================================================================================================
6462
| VIEW
@@ -70,8 +68,8 @@ public record TopicViewModel: ITopicViewModel, ICoreTopicViewModel, IAssociatedT
7068
| TITLE
7169
\-------------------------------------------------------------------------------------------------------------------------*/
7270
/// <inheritdoc />
73-
[Required, NotNull, DisallowNull]
74-
public string? Title { get; init; }
71+
[Required]
72+
public string Title { get; init; } = default!;
7573

7674
/*==========================================================================================================================
7775
| IS HIDDEN?
@@ -107,6 +105,4 @@ public record TopicViewModel: ITopicViewModel, ICoreTopicViewModel, IAssociatedT
107105
public TopicViewModel? Parent { get; init; }
108106

109107
} //Class
110-
} //Namespace
111-
112-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
108+
} //Namespace

OnTopic.ViewModels/_contentTypes/VideoTopicViewModel.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
using System.ComponentModel.DataAnnotations;
88
using System.Diagnostics.CodeAnalysis;
99

10-
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
11-
1210
namespace OnTopic.ViewModels {
1311

1412
/*============================================================================================================================
@@ -30,8 +28,8 @@ public record VideoTopicViewModel: PageTopicViewModel {
3028
/// <summary>
3129
/// Provides a URL reference to a video to display on the page.
3230
/// </summary>
33-
[Required, NotNull, DisallowNull]
34-
public Uri? VideoUrl { get; init; }
31+
[Required]
32+
public Uri VideoUrl { get; init; } = default!;
3533

3634
/*==========================================================================================================================
3735
| POSTER URL
@@ -42,6 +40,4 @@ public record VideoTopicViewModel: PageTopicViewModel {
4240
public Uri? PosterUrl { get; init; }
4341

4442
} //Class
45-
} //Namespace
46-
47-
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
43+
} //Namespace

0 commit comments

Comments
 (0)