You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
NET-1872 S3900 FP: with nullable context enabled #5217
When nullable context is enabled (feature which was introduced in C# 8 / .NET Framework 4.8), or when [NotNull] attributes are used, rule S3900 should assume that reference type parameters are non nullable unless explicitly marked as nullable (e.g. string?).
Having in mind that the rule will be rewritten in MMF-2401 , which will be coming in the next few months, we should still aim at reducing the noise with the current analyzer when nullable context is enabled or when netstandard System.Diagnostics.CodeAnalysis.NotNullAttribute is used.
On the public API boundary, the nullable annotation specifies what the API expects in terms of nullability. If a parameter is specified as being expected to be non-nullable the "NotNull" check is especially important. In the dotnet-runtime repo, it is mandatory to do such checks. See e.g. the Path.Combine API's implementation:
This is true for real public APIs where the clients of the API are unknown. If the public API is not published but is part of a closed solution, any clients consuming the API are known. In that case, raising S3900 on public APIs creates a lot of FPs. The analyzer can not distinguish between these two scenarios, but the user can. Our conclusion is to create a new rule complementing S3900. The new rule is for the real public API case only (Working title: "Non-nullable parameters of public methods should be validated against null"). Once we do have the rule specified and implemented, we will change S3900 to behave like in the known clients scenario like so:
#nullable enable
M1(SampleClasssample)// Expecting a non-nullable reference type{// S3900: FP. We will remove any S3900 issues in the future// New rule: Raise an issue here and only here. This rule will be opt-in and not enabled by default.}M2(SampleClass?sample)// Expecting a nullable reference type{// S3900: Triggers as before// New rule: Doesn't trigger}
This distinction between the two rules seems suitable if nullable reference types are enabled (as default in new projects since C# 10).
I haven't tested the Roslyn behaviour of the unreasonable M3([NotNull] SampleClass? sample), but for sure you should also inspect the nullable attribute family and define which rules should trigger,
And what are you plans, if nullable reference types are diabled? Always S3900 as before?
@pavel-mikula-sonarsource Thanks for updating this recently. I'm encouraged that some progress is being made as it's been quite a while since this was opened.
In the interim, is there a recommendation to remove S3900 altogether?
I have a ruleset that includes it because it's relevant for legacy projects, so I still want the suggestion.. but not when adding != null checks then result in another warning that I'm checking for null on a non-nullable reference type.
pavel-mikula-sonarsource commented on Jun 10, 2025
@DSmith-VERX I'd recommend to activate the rule on projects where it makes sense. Generally, not all rules are suitable for all projects.
The previous message is just technical migration. The ticket is not scheduled yet. So it basically only says that it's still alive. S3900 will generally require more attention and we're considering splitting the rule into two.
@pavel-mikula-sonarsource I think null value handling makes sense on every project. Is there another rule that will tell you to validate the nullable ref types when they actually are nullable?
Creating a whole separate quality profile for this one difference seems like overkill, but I can do it. Unfortunately, I work on many large legacy solutions where not every project in the solution uses the same framework version or nullable setting though.
Reacted by Pavel Mikula
pavel-mikula-sonarsource commented on Jun 10, 2025
Activity
[-]Fix S3900 FP with nullable context enabled[/-][+]S3900 FP: with nullable context enabled[/+]martin-strecker-sonarsource commentedon Apr 4, 2023
On the public API boundary, the nullable annotation specifies what the API expects in terms of nullability. If a parameter is specified as being expected to be non-nullable the "NotNull" check is especially important. In the dotnet-runtime repo, it is mandatory to do such checks. See e.g. the
Path.CombineAPI's implementation:https://github.com/dotnet/runtime/blob/e579ccb60acb044453f2cf1907482b165658488e/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs#L344-L373
APIs that accept a nullable reference type are handling the null case gracefully instead. see e.g.
https://github.com/dotnet/runtime/blob/e579ccb60acb044453f2cf1907482b165658488e/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs#L320-L327
This is true for real public APIs where the clients of the API are unknown. If the public API is not published but is part of a closed solution, any clients consuming the API are known. In that case, raising S3900 on public APIs creates a lot of FPs. The analyzer can not distinguish between these two scenarios, but the user can. Our conclusion is to create a new rule complementing S3900. The new rule is for the real public API case only (Working title: "Non-nullable parameters of public methods should be validated against null"). Once we do have the rule specified and implemented, we will change S3900 to behave like in the known clients scenario like so:
The new rule issue is #7035.
milbrandt commentedon Apr 4, 2023
This distinction between the two rules seems suitable if nullable reference types are enabled (as default in new projects since C# 10).
I haven't tested the Roslyn behaviour of the unreasonable
M3([NotNull] SampleClass? sample), but for sure you should also inspect the nullable attribute family and define which rules should trigger,And what are you plans, if nullable reference types are diabled? Always S3900 as before?
1 remaining item
[-]S3900 FP: with nullable context enabled[/-][+]NET-1872 S3900 FP: with nullable context enabled[/+]pavel-mikula-sonarsource commentedon Jun 6, 2025
Internal ticket NET-1872
DSmith-VERX commentedon Jun 6, 2025
@pavel-mikula-sonarsource Thanks for updating this recently. I'm encouraged that some progress is being made as it's been quite a while since this was opened.
In the interim, is there a recommendation to remove S3900 altogether?
I have a ruleset that includes it because it's relevant for legacy projects, so I still want the suggestion.. but not when adding
!= nullchecks then result in another warning that I'm checking for null on a non-nullable reference type.pavel-mikula-sonarsource commentedon Jun 10, 2025
@DSmith-VERX I'd recommend to activate the rule on projects where it makes sense. Generally, not all rules are suitable for all projects.
The previous message is just technical migration. The ticket is not scheduled yet. So it basically only says that it's still alive. S3900 will generally require more attention and we're considering splitting the rule into two.
DSmith-VERX commentedon Jun 10, 2025
@pavel-mikula-sonarsource I think null value handling makes sense on every project. Is there another rule that will tell you to validate the nullable ref types when they actually are nullable?
Creating a whole separate quality profile for this one difference seems like overkill, but I can do it. Unfortunately, I work on many large legacy solutions where not every project in the solution uses the same framework version or nullable setting though.
pavel-mikula-sonarsource commentedon Jun 10, 2025
The other rule is the proposal in #7035 that Martin mentioned above in this thread.