Code analysis
Apparence
Links
Enable additional rules
Those rules are enabled by default.
Edit the project file to enable additional rules:
MyProject.csproj |
<PropertyGroup>
<!-- ... -->
<AnalysisLevel>latest-recommended</AnalysisLevel>
</PropertyGroup>
|
Code style analysis
# verify that all code is correctly formatted
dotnet format --verify-no-changes
# format all code
dotnet format
|
- Configuration files for code analysis rules
- An example of .editorconfig file with the default options
- Code-style rules IDExxxx
- Change encoding
.editorconfig |
###############################
# Core EditorConfig Options #
###############################
root = true
# All files
[*]
indent_style = space
insert_final_newline = true
charset = utf-8
# XML project files
[*.csproj]
indent_size = 2
# JSON config files
[*.json]
indent_size = 2
# C# code files
[*.cs]
indent_size = 4
trim_trailing_whitespace = true
###############################
# Analyzer configuration #
###############################
# set the rules severity to warning
dotnet_analyzer_diagnostic.severity = warning
# speller
dotnet_diagnostic.VSSpell001.severity = suggestion
dotnet_diagnostic.VSSpell002.severity = suggestion
###############################
# .NET Coding Conventions #
###############################
[*.cs]
# Organize usings
dotnet_sort_system_directives_first = true
###############################
# Code Quality configuration #
###############################
# CA1826: Use property instead of Linq Enumerable method
# Exclude FirstOrDefault and LastOrDefault methods
dotnet_code_quality.CA1826.exclude_ordefault_methods = true
###############################
# Style configuration #
###############################
# IDE0003 / IDE0009: this and Me preferences
dotnet_style_qualification_for_field = true
# IDE0007 / IDE0008: 'var' preferences
csharp_style_var_for_built_in_types = true
csharp_style_var_when_type_is_apparent = true
csharp_style_var_elsewhere = true : silent
# IDE0011: Add braces
csharp_prefer_braces = when_multiline
# IDE0022: Use expression body for methods
csharp_style_expression_bodied_methods = when_on_single_line
# IDE0160 / IDE0161: Namespace declaration preferences
csharp_style_namespace_declarations = file_scoped : error
###############################
# Disabled rules #
###############################
# IDE0046: Use conditional expression for return
dotnet_diagnostic.IDE0046.severity = suggestion
# IDE0058: Remove unnecessary expression value
dotnet_diagnostic.IDE0058.severity = none
# CA1305: Specify IFormatProvider
dotnet_diagnostic.CA1305.severity = none
# CA1310: Specify StringComparison for correctness
dotnet_diagnostic.CA1310.severity = none
# Specify CultureInfo
dotnet_diagnostic.CA1304.severity = suggestion
# Specify a culture
dotnet_diagnostic.CA1311.severity = suggestion
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.upper_case_style.capitalization = all_upper
dotnet_naming_style.camel_case_style.capitalization = camel_case
# Use UpperCase for constant fields
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style
dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning
# Use camelCase for variables
dotnet_naming_symbols.local_symbol.applicable_kinds = local
dotnet_naming_rule.variables_should_be_camel_case.symbols = local_symbol
dotnet_naming_rule.variables_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.variables_should_be_camel_case.severity = warning
# Use camelCase for parameters
dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter
dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameter_symbol
dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.parameters_should_be_camel_case.severity = warning
# Async methods should have "Async" suffix
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
dotnet_naming_symbols.any_async_methods.applicable_kinds = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
dotnet_naming_symbols.any_async_methods.required_modifiers = async
dotnet_naming_style.end_in_async.required_prefix =
dotnet_naming_style.end_in_async.required_suffix = Async
dotnet_naming_style.end_in_async.capitalization = pascal_case
dotnet_naming_style.end_in_async.word_separator =
|
Visual Studio Code integration
settings.json |
"omnisharp.enableRoslynAnalyzers": true,
"omnisharp.enableEditorConfigSupport": true,
|
Visual Studio
Set the scope of live code analysis
- Tools → Options
- Text Editor → C# → Advanced
- Run background code analysis for: Current document
- Show compiler errors and warnings for: Open documents
Roslynator
- Install the Roslynator extension in Visual Studio or Visual Studio Code
- Configure Roslynator on a user-wide basis
- vscode → Ctrl + Shift + P → enter roslynator → select Roslynator: Open Default Configuration File (.roslynatorconfig)
~/.local/share/JosefPihrt/Roslynator/.roslynatorconfig |
is_global = true
# enable all analyzers by default and set the severity to warning
roslynator_analyzers.enabled_by_default = true
dotnet_analyzer_diagnostic.category-roslynator.severity = warning
# enable all refactorings
roslynator_refactorings.enabled = true
# enable all compiler diagnostic fixes
roslynator_compiler_diagnostic_fixes.enabled = true
# Options
roslynator_accessibility_modifiers = explicit
roslynator_accessor_braces_style = single_line_when_expression_is_on_single_line
roslynator_array_creation_type_style = implicit_when_type_is_obvious
roslynator_arrow_token_new_line = before
roslynator_binary_operator_new_line = before
roslynator_blank_line_after_file_scoped_namespace_declaration = true
roslynator_blank_line_between_closing_brace_and_switch_section = false
roslynator_blank_line_between_single_line_accessors = false
roslynator_blank_line_between_using_directives = never
roslynator_block_braces_style = single_line_when_empty
#roslynator_body_style = block|expression
roslynator_conditional_operator_condition_parentheses_style = omit
roslynator_conditional_operator_new_line = beforeroslynator_configure_await = false
roslynator_doc_comment_summary_style = multi_line
roslynator_empty_string_style = field
roslynator_enum_flag_value_style = decimal_number
roslynator_enum_has_flag_style = method
roslynator_equals_token_new_line = before
roslynator_infinite_loop_style = while
roslynator_max_line_length = 140
roslynator_new_line_at_end_of_file = false
roslynator_new_line_before_while_in_do_statement = false
roslynator_null_conditional_operator_new_line = before
roslynator_null_check_style = pattern_matching
roslynator_object_creation_parentheses_style = omit
roslynator_object_creation_type_style = implicit_when_type_is_obvious
roslynator_prefix_field_identifier_with_underscore = false
roslynator_suppress_unity_script_methods = true
roslynator_use_anonymous_function_or_method_group = method_group
roslynator_use_block_body_when_declaration_spans_over_multiple_lines = true
roslynator_use_block_body_when_expression_spans_over_multiple_lines = true
roslynator_use_var_instead_of_implicit_object_creation = true
# Analyzers
# Add blank line between single-line declarations
dotnet_diagnostic.rcs0012.severity = none
# Remove braces from if-else
dotnet_diagnostic.rcs1004.severity = none
# Use explicit type instead of 'var' (when the type is not obvious)
dotnet_diagnostic.rcs1008.severity = none
# Use explicit type instead of 'var' (foreach variable)
dotnet_diagnostic.rcs1009.severity = none
# Use explicit type instead of 'var' (when the type is obvious)
dotnet_diagnostic.rcs1012.severity = none
# Avoid unnecessary boxing of value type
dotnet_diagnostic.rcs1198.severity = none
# Mark publicly visible type with DebuggerDisplay attribute
dotnet_diagnostic.rcs1223.severity = none
|
Roslynator CLI
# install
dotnet tool install -g roslynator.dotnet.cli
roslynator analyze \
--analyzer-assemblies \
~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/common \
~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/analyzers
|
![]() |
To fix the error: Could not load file or assembly 'System.Composition.AttributedModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
|
Code coverage
# add the XunitXML.TestLogger nuget package to the unit test project
dotnet add package XunitXML.TestLogger
# run unit tests with Coverlet data collector and log the results
dotnet test MySolution.sln --collect="XPlat Code Coverage" --logger:"xunit;LogFilePath=TestResults.xml"
# creates a TestResults.xml report and a TestResults/[guid]/coverage.cobertura.xml report
# extract the line coverage:
xmllint --xpath "string(/coverage/@line-rate)" TestResults/[guid]/coverage.cobertura.xml
sed -n -r 's/<coverage line-rate="([0-9.]+)".*/\1/p' TestResults/[guid]/coverage.cobertura.xml
# install the ReportGenerator tool
dotnet tool install -g dotnet-reportgenerator-globaltool
# get a text summary report from all the cobertura reports
reportgenerator -reports:"*/TestResults/*/coverage.cobertura.xml" -targetdir:CoverageReport -reporttypes:TextSummary
# creates CoverageReport/TextSummary.txt
# extract the line coverage:
sed -n -r 's/Line coverage: ([0-9.]+)%/\1/p' CoverageReport/Summary.txt
|
Ignore generated code
Create an .editorconfig file in a folder to not run code analysis on the files of this folder.
MyWebapi/DataAccess/.editorconfig |
[*]
generated_code = true
dotnet_analyzer_diagnostic.severity = silent
|