I have created a small dotnetstandard 2.1
library project in a solution. I want to test out using Nullable Reference Types. As part of this, I want to have appropriate compilation errors and warnings.
TLDR;
I want to know how to setup the CA1062 code quality settings in .editorconfig
correctly.
I have added the following nuget
packages to the project:
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Ardalis.GuardClauses" Version="1.4.2" />
</ItemGroup>
This includes the various code analysis packages and also Steve Smith's nice Guard Clauses library.
Nullable Reference Types has been enabled using <Nullable>enable</Nullable>
in the project.
And I have a class which in the real world would be a nice implementation that actually did something:
using System;
using MyGuards;
namespace EditorConfigIssues
{
public static class TestEditorConfig
{
public static void TestMethod(MyParam input)
{
string x = input.Check;
Console.WriteLine(x);
}
}
public class MyParam
{
public MyParam(string check) => Check = check;
public string Check { get; }
}
}
In the solution I have added a simple Guard library which is another dotnetstandard 2.1
project.
using System;
namespace MyGuards
{
public static class FakeGuard
{
public static void Validate(object obj)
{
if (obj == null)
throw new ArgumentNullException();
}
}
}
NOTE: This is not in competition of the GuardClauses library - just using to contrast editorconfig with!
I have added an .editorconfig
to the root of solution with the following diagnostic checks:
dotnet_diagnostic.CA1062.severity = error
dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true
So with this in place, when I compile I get the following:
So everything is as I expect so far. I am not using any guards yet.
So lets try and implement the guard clauses from Steve Smiths Guard Library to get rid of the error.
So we add the following to TestEditorConfig.TestMethod
:
Guard.Against.Null(input, nameof(input));
and tweak the .editorconfig
with:
dotnet_code_quality.CA1062.null_check_validation_methods = Ardalis.GuardClauses.Guard.Against.Null
Excellent, all is good. The error has disappeared.
But now I want to use my own guard. So we replace the initial guard check in TestEditorConfig.TestMethod
with:
FakeGuard.Validate(input);
and replace the null_check_validation_methods in .editorconfig
with:
dotnet_code_quality.CA1062.null_check_validation_methods = FakeGuard.Validate
The keyword "dotnet_code_quality.CA1062.exclude_extension_method_this_parameter" is unknown
The keyword "dotnet_code_quality.CA1062.null_check_validation_methods" is unknown
I have been checking out this link MS Docs Code Quality and tried various combinations for the FakeGuard, including:
Curiously, in a different solution, then I don't get any complaints about the CA1062 editorconfig settings in the Error Window. And in there I have been unable to get the null_check_validation_methods
working - hence putting together this solution. This has been bugging me for a month or two, but finally getting the energy to put things together at the moment.
If I copy the FakeGuard file to the Library project, then the error message disappears. But why does this not work in a different project in the solution.
OK... I posted on the roslyn-analyzers
issues - here - https://github.com/dotnet/roslyn-analyzers/issues/3451
As it turns out this is a bug. For now here is the suggested workaround:
using System;
[AttributeUsage(AttributeTargets.Parameter)]
internal sealed class ValidatedNotNullAttribute : Attribute { }
namespace MyGuards
{
/// <summary>
/// Checks stuff.
/// </summary>
public static class FakeGuard
{
/// <summary>
/// No more nulls.
/// </summary>
/// <param name="obj"></param>
public static void Validate([ValidatedNotNull] object obj)
{
if (obj == null)
throw new ArgumentNullException();
}
}
}