{
"$type": "site.standard.document",
"canonicalUrl": "https://johnnyreilly.com/posts/eslint-your-csharp-in-vs-code-with-roslyn-analyzers",
"description": "ESLint provides linting for TypeScript and JavaScript in VS Code. A similar experience is available for C# in VS Code through Roslyn Analyzers.",
"path": "/posts/eslint-your-csharp-in-vs-code-with-roslyn-analyzers",
"publishedAt": "2022-04-06T00:00:00.000Z",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"c#",
"vs code",
"javascript",
"asp.net"
],
"textContent": "ESLint provides a great linting experience for TypeScript and JavaScript in VS Code. The suggestions, fixes and ignore options make creating clean code a joy. A similar experience is available for Cin VS Code through Roslyn Analyzers - this post tells us more.\n\n\n\nLinting and C\nJavaScript and TypeScript benefit from a tremendous tooling ecosystem which allows us to simply format and lint our codebases as we're editing. Similar tooling exists for C#. Previously I wrote about using dotnet-format to have a Prettier-like experience for formatting our C#. If that last post focussed on formatting C#; looking through the lens of Prettier, this post focusses on linting; looking through the lens of ESLint.\n\nRoslyn Analyzers\n\nThere's often overlap between linting and formatting tooling; and so it goes with Cas well. Linting and formatting in the .NET space make use of the Roslyn Analyzers:\n\n> Roslyn analyzers analyze your code for style, quality and maintainability, design and other issues. The documentation for Roslyn Analyzers can be found at docs.microsoft.com/dotnet/fundamentals/code-analysis/overview.\n\nTo learn more about them, it's worth reading the excellent piece on the topic by Ian Griffiths.\n\n\"Analyse this\"\n\nIn order that we can see what the linting experience is like in VS Code, we're going to need a project to work on. We have the .NET 6 SDK installed, so we'll create ourselves a project:\n\nWe have the Cextension installed already, but we're getting no feedback on the code. Maybe it's already beautiful?\n\nOr maybe not. We're going to need an .editorconfig file to control all the code style settings. You can create this directly using the dotnet CLI like so;\n\nOnce this runs, it creates a file with all of the settings in with their default values. Alongside that, we need to wake VS Code up to our brave new world by setting the following in our settings.json:\n\nOr alternatively, use the GUI in VS Code to set these settings directly:\n\nIt's then a good idea to turn OmniSharp off and on again, so it picks up these changes:\n\nThen, excitingly, we start to see code analysis, or linting, messages in the problems pane of VS Code:\n\nIt's possible to use the dotnet-format command to surface this information:\n\nNote the IDE0052: Private member 'WeatherForecastController._logger' can be removed as the value assigned to it is never read message above.\n\nNow fail my build!\n\nThis is all very exciting - we've a world of extra linting at our fingertips! But what's a touch disappointing, is that the above information isn't surfaced in my build. What if as a team we commit to a particular code style? If I can't enforce that in the build, it's likely not going to happen.\n\nSo what do I do? Well, the information is out there on how to do this, but it's easy to miss. You can find the details here. We update our AnalyseThis.csproj to include an EnforceCodeStyleInBuild setting like so:\n\nWe're going to replace our exhaustive .editorconfig file with a much simpler one:\n\nDo you see what we did here? We told our build to treat Style diagnostics (lints) as warnings. Once OmniSharp picks this up, more linting messages start to appear in the problems pane of VS Code:\n\nAnd what's more, if we attempt to build, guess what?\n\nThat's right! The same messages from the problems pane are now surfaced in our build as warnings. And we can kick it up a notch too; let's make them errors:\n\nOnce OmniSharp catches up we see our warnings transform into errors:\n\nAnd if we build...\n\nYes! Our style diagnostics are now failing the build. This is terrific!\n\nCategories\n\nIt's worth pausing a second and considering the category upgrade we did here:\n\nThere's a number of different categories that encapsulate groups of rules, they're documented here. Taken from there you can see the wealth of different categories that exist:\n\n| Category | Description | EditorConfig value |\n| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |\n| Design rules | Design rules support adherence to the .NET Framework Design Guidelines. | dotnet_analyzer_diagnostic.category-Design.severity |\n| Documentation rules | Documentation rules support writing well-documented libraries through the correct use of XML documentation comments for externally visible APIs. | dotnet_analyzer_diagnostic.category-Documentation.severity |\n| Globalization rules | Globalization rules support world-ready libraries and applications. | dotnet_analyzer_diagnostic.category-Globalization.severity |\n| Portability and interoperability rules | Portability rules support portability across different platforms. Interoperability rules support interaction with COM clients. | dotnet_analyzer_diagnostic.category-Interoperability.severity |\n| Maintainability rules | Maintainability rules support library and application maintenance. | dotnet_analyzer_diagnostic.category-Maintainability.severity |\n| Naming rules | Naming rules support adherence to the naming conventions of the .NET design guidelines. | dotnet_analyzer_diagnostic.category-Naming.severity |\n| Performance rules | Performance rules support high-performance libraries and applications. | dotnet_analyzer_diagnostic.category-Performance.severity |\n| SingleFile rules | Single-file rules support single-file applications. | dotnet_analyzer_diagnostic.category-SingleFile.severity |\n| Reliability rules | Reliability rules support library and application reliability, such as correct memory and thread usage. | dotnet_analyzer_diagnostic.category-Reliability.severity |\n| Security rules | Security rules support safer libraries and applications. These rules help prevent security flaws in your program. | dotnet_analyzer_diagnostic.category-Security.severity |\n| Style rules | Style rules support consistent code style in your codebase. These rules start with the \"IDE\" prefix. | dotnet_analyzer_diagnostic.category-Style.severity |\n| Usage rules | Usage rules support proper usage of .NET. | dotnet_analyzer_diagnostic.category-Usage.severity |\n| N/A | You can use this EditorConfig value to enable the following rules: IDE0051, IDE0064, IDE0076. While these rules start with \"IDE\", they are not technically part of the Style category. | dotnet_analyzer_diagnostic.category-CodeQuality.severity |\n\nThe IDE0052 information we saw when we used dotnet format earlier is technically part of the CodeQuality category. If we wanted to, we we could dial that up that category to an error like so:\n\nOpt out of rules\n\nAs it turns out, I disagree with the complaints I'm getting on the codebase right now, so I'd like to dial those down to ignore. To do that globally, you simply put configuration in the .editorconfig to reflect that:\n\nWhat we're doing here is saying \"upgrade all style rules to be errors, but IDE0008, IDE0058 and IDE0160 (which are style rules) - ignore those; don't tell me about them\".\n\nNow I'm not going to be bothered by those errors in future. Great.\n\nDial up information to warning\n\nIf we look again at our problems pane in VS Code, we can see there's an entry there. It's not an error, it's not a warning. It's information:\n\nLet's say we want to take that and dial it up to be a warning, such that it surfaces in the build too. We can with a simple addition to our .editorconfig:\n\nOnce OmniSharp notices:\n\nAnd if we run the build, there it is!\n\nDeactivate linting partially\n\nLet's say we want to ignore that one warning. We'd like the equivalent functionality to // eslint-disable-next-line. That doesn't exist alas. However, what does is the equivalent to this:\n\nIn our case what we'd do is this:\n\nOr to be more specific:\n\nAnd now we can opt out of that rule in this specific place - whilst maintaining it more generally.\n\nConclusion\n\nThere's powerful linting tools in C#, hopefully this guide has made it easier for you to surface them, control them and apply them both to VS Code and to your build.\n\nThanks to Joey Robichaud, Tim Heuer and Youssef Victor for some excellent pointers that fed into the writing of this post. You can see the help they provided here.",
"title": "ESLint your C# in VS Code with Roslyn Analyzers"
}