static-analysis

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

.NET Static Analysis

.NET静态分析

Built-in Analyzers

内置分析器

.NET Analyzers

.NET Analyzers

.NET SDK includes analyzers for code quality and style. Enable in project file:
xml
<PropertyGroup>
  <!-- Enable all .NET analyzers -->
  <EnableNETAnalyzers>true</EnableNETAnalyzers>

  <!-- Analysis level (latest, 8.0, 7.0, etc.) -->
  <AnalysisLevel>latest</AnalysisLevel>

  <!-- Analysis mode: Default, Minimum, Recommended, All -->
  <AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>
.NET SDK 包含用于代码质量与代码风格的分析器。可在项目文件中启用:
xml
<PropertyGroup>
  <!-- Enable all .NET analyzers -->
  <EnableNETAnalyzers>true</EnableNETAnalyzers>

  <!-- Analysis level (latest, 8.0, 7.0, etc.) -->
  <AnalysisLevel>latest</AnalysisLevel>

  <!-- Analysis mode: Default, Minimum, Recommended, All -->
  <AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>

Analysis Categories

分析类别

CategoryPrefixFocus
DesignCA1xxxAPI design guidelines
GlobalizationCA2xxxInternationalization
PerformanceCA18xxPerformance optimizations
SecurityCA2xxx, CA3xxxSecurity vulnerabilities
UsageCA2xxxCorrect API usage
NamingCA17xxNaming conventions
ReliabilityCA2xxxError handling, resources
类别前缀关注方向
设计CA1xxxAPI设计准则
全球化CA2xxx国际化
性能CA18xx性能优化
安全CA2xxx, CA3xxx安全漏洞
使用规范CA2xxxAPI正确使用方式
命名CA17xx命名规范
可靠性CA2xxx错误处理、资源管理

Running Analysis

运行分析

With Build

与构建同步运行

bash
undefined
bash
undefined

Build with analyzers (default)

Build with analyzers (default)

dotnet build
dotnet build

Ensure analyzers run

Ensure analyzers run

dotnet build /p:RunAnalyzersDuringBuild=true
dotnet build /p:RunAnalyzersDuringBuild=true

Treat warnings as errors

Treat warnings as errors

dotnet build /p:TreatWarningsAsErrors=true
dotnet build /p:TreatWarningsAsErrors=true

Run only analyzers (no compile)

Run only analyzers (no compile)

dotnet build /p:RunAnalyzers=true /p:RunCodeAnalysis=true
undefined
dotnet build /p:RunAnalyzers=true /p:RunCodeAnalysis=true
undefined

As Separate Step

作为独立步骤运行

bash
undefined
bash
undefined

Format check (style only)

Format check (style only)

dotnet format --verify-no-changes
dotnet format --verify-no-changes

Format and fix

Format and fix

dotnet format
dotnet format

Analyze specific project

Analyze specific project

dotnet build src/MyApp/MyApp.csproj /p:TreatWarningsAsErrors=true
undefined
dotnet build src/MyApp/MyApp.csproj /p:TreatWarningsAsErrors=true
undefined

Configuring Rules

配置规则

EditorConfig

EditorConfig

ini
undefined
ini
undefined

.editorconfig

.editorconfig

root = true
[*.cs]
root = true
[*.cs]

Naming conventions

Naming conventions

dotnet_naming_rule.private_fields_should_be_camel_case.severity = warning dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields dotnet_naming_rule.private_fields_should_be_camel_case.style = camel_case_style
dotnet_naming_symbols.private_fields.applicable_kinds = field dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_style.camel_case_style.capitalization = camel_case dotnet_naming_style.camel_case_style.required_prefix = _
dotnet_naming_rule.private_fields_should_be_camel_case.severity = warning dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields dotnet_naming_rule.private_fields_should_be_camel_case.style = camel_case_style
dotnet_naming_symbols.private_fields.applicable_kinds = field dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_style.camel_case_style.capitalization = camel_case dotnet_naming_style.camel_case_style.required_prefix = _

Code style

Code style

csharp_style_var_for_built_in_types = true:suggestion csharp_style_expression_bodied_methods = when_on_single_line:suggestion csharp_prefer_braces = true:warning
csharp_style_var_for_built_in_types = true:suggestion csharp_style_expression_bodied_methods = when_on_single_line:suggestion csharp_prefer_braces = true:warning

Analyzer rules

Analyzer rules

dotnet_diagnostic.CA1062.severity = warning # Validate arguments dotnet_diagnostic.CA2007.severity = none # Don't require ConfigureAwait dotnet_diagnostic.IDE0044.severity = warning # Make field readonly
undefined
dotnet_diagnostic.CA1062.severity = warning # Validate arguments dotnet_diagnostic.CA2007.severity = none # Don't require ConfigureAwait dotnet_diagnostic.IDE0044.severity = warning # Make field readonly
undefined

GlobalAnalyzerConfig

GlobalAnalyzerConfig

ini
undefined
ini
undefined

.globalconfig

.globalconfig

is_global = true
is_global = true

Apply to all projects

Apply to all projects

dotnet_diagnostic.CA1062.severity = warning dotnet_diagnostic.CA2000.severity = error
undefined
dotnet_diagnostic.CA1062.severity = warning dotnet_diagnostic.CA2000.severity = error
undefined

Project-Level

项目级配置

xml
<PropertyGroup>
  <!-- Suppress in entire project -->
  <NoWarn>$(NoWarn);CA1062;CA2007</NoWarn>

  <!-- Treat specific as error -->
  <WarningsAsErrors>$(WarningsAsErrors);CA2000</WarningsAsErrors>
</PropertyGroup>
xml
<PropertyGroup>
  <!-- Suppress in entire project -->
  <NoWarn>$(NoWarn);CA1062;CA2007</NoWarn>

  <!-- Treat specific as error -->
  <WarningsAsErrors>$(WarningsAsErrors);CA2000</WarningsAsErrors>
</PropertyGroup>

Suppressing Warnings

抑制警告

Code-Level Suppression

代码级抑制

csharp
// Suppress on member
[SuppressMessage("Design", "CA1062:Validate arguments",
    Justification = "Validated by framework")]
public void Process(Request request) { }

// Suppress on line
#pragma warning disable CA1062
public void Process(Request request) { }
#pragma warning restore CA1062

// Suppress all in file
[assembly: SuppressMessage("Design", "CA1062")]
csharp
// Suppress on member
[SuppressMessage("Design", "CA1062:Validate arguments",
    Justification = "Validated by framework")]
public void Process(Request request) { }

// Suppress on line
#pragma warning disable CA1062
public void Process(Request request) { }
#pragma warning restore CA1062

// Suppress all in file
[assembly: SuppressMessage("Design", "CA1062")]

Global Suppressions

全局抑制

csharp
// GlobalSuppressions.cs
using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Design", "CA1062",
    Scope = "namespaceanddescendants",
    Target = "~N:MyApp.Controllers")]
csharp
// GlobalSuppressions.cs
using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Design", "CA1062",
    Scope = "namespaceanddescendants",
    Target = "~N:MyApp.Controllers")]

Common Analyzer Rules

常见分析器规则

CA1062 - Validate Arguments

CA1062 - 验证参数

csharp
// Warning: parameter 'request' is never validated
public void Process(Request request)
{
    request.Execute();  // CA1062
}

// Fixed
public void Process(Request request)
{
    ArgumentNullException.ThrowIfNull(request);
    request.Execute();
}
csharp
// Warning: parameter 'request' is never validated
public void Process(Request request)
{
    request.Execute();  // CA1062
}

// Fixed
public void Process(Request request)
{
    ArgumentNullException.ThrowIfNull(request);
    request.Execute();
}

CA2007 - ConfigureAwait

CA2007 - 使用ConfigureAwait

csharp
// Warning in library code
await SomeAsync();  // CA2007

// Fixed
await SomeAsync().ConfigureAwait(false);

// Or suppress in application code (.editorconfig)
dotnet_diagnostic.CA2007.severity = none
csharp
// Warning in library code
await SomeAsync();  // CA2007

// Fixed
await SomeAsync().ConfigureAwait(false);

// Or suppress in application code (.editorconfig)
dotnet_diagnostic.CA2007.severity = none

CA1822 - Mark Members Static

CA1822 - 将成员标记为静态

csharp
// Warning: can be static
public int Calculate(int x) => x * 2;  // CA1822

// Fixed
public static int Calculate(int x) => x * 2;
csharp
// Warning: can be static
public int Calculate(int x) => x * 2;  // CA1822

// Fixed
public static int Calculate(int x) => x * 2;

IDE0044 - Make Field Readonly

IDE0044 - 将字段设为只读

csharp
// Warning
private int _value;  // IDE0044

// Fixed
private readonly int _value;
csharp
// Warning
private int _value;  // IDE0044

// Fixed
private readonly int _value;

CA2000 - Dispose Objects

CA2000 - 释放对象

csharp
// Warning: not disposed
public void Process()
{
    var stream = new FileStream("file.txt", FileMode.Open);
}  // CA2000

// Fixed
public void Process()
{
    using var stream = new FileStream("file.txt", FileMode.Open);
}
csharp
// Warning: not disposed
public void Process()
{
    var stream = new FileStream("file.txt", FileMode.Open);
}  // CA2000

// Fixed
public void Process()
{
    using var stream = new FileStream("file.txt", FileMode.Open);
}

dotnet format

dotnet format

Check Formatting

检查格式

bash
undefined
bash
undefined

Check without changes

Check without changes

dotnet format --verify-no-changes
dotnet format --verify-no-changes

Check specific files

Check specific files

dotnet format --include "src/**/*.cs" --verify-no-changes
dotnet format --include "src/**/*.cs" --verify-no-changes

Exclude paths

Exclude paths

dotnet format --exclude "/Migrations/"
undefined
dotnet format --exclude "/Migrations/"
undefined

Apply Fixes

应用修复

bash
undefined
bash
undefined

Fix all issues

Fix all issues

dotnet format
dotnet format

Fix style issues only

Fix style issues only

dotnet format style
dotnet format style

Fix analyzers only

Fix analyzers only

dotnet format analyzers
dotnet format analyzers

Fix specific severity

Fix specific severity

dotnet format --severity warn
undefined
dotnet format --severity warn
undefined

Targeting

目标指定

bash
undefined
bash
undefined

Whitespace only

Whitespace only

dotnet format whitespace
dotnet format whitespace

Style and analyzers

Style and analyzers

dotnet format style dotnet format analyzers
dotnet format style dotnet format analyzers

Specific diagnostics

Specific diagnostics

dotnet format --diagnostics CA1062 IDE0044
undefined
dotnet format --diagnostics CA1062 IDE0044
undefined

Third-Party Analyzers

第三方分析器

StyleCop.Analyzers

StyleCop.Analyzers

bash
dotnet add package StyleCop.Analyzers
ini
undefined
bash
dotnet add package StyleCop.Analyzers
ini
undefined

.editorconfig

.editorconfig

Configure StyleCop rules

Configure StyleCop rules

dotnet_diagnostic.SA1101.severity = none # Prefix local calls with this dotnet_diagnostic.SA1200.severity = none # Using directives placement dotnet_diagnostic.SA1633.severity = none # File header
undefined
dotnet_diagnostic.SA1101.severity = none # Prefix local calls with this dotnet_diagnostic.SA1200.severity = none # Using directives placement dotnet_diagnostic.SA1633.severity = none # File header
undefined

Roslynator

Roslynator

bash
dotnet add package Roslynator.Analyzers
bash
dotnet add package Roslynator.Analyzers

SonarAnalyzer

SonarAnalyzer

bash
dotnet add package SonarAnalyzer.CSharp
bash
dotnet add package SonarAnalyzer.CSharp

CI Integration

CI集成

Quality Gate Script

质量门脚本

bash
#!/bin/bash
bash
#!/bin/bash

Run build with analysis

Run build with analysis

dotnet build --no-restore /p:TreatWarningsAsErrors=true
dotnet build --no-restore /p:TreatWarningsAsErrors=true

Check format

Check format

dotnet format --verify-no-changes
dotnet format --verify-no-changes

Exit with error if any issues

Exit with error if any issues

exit $?
undefined
exit $?
undefined

Azure DevOps

Azure DevOps

yaml
- task: DotNetCoreCLI@2
  displayName: 'Build with Analysis'
  inputs:
    command: build
    arguments: '/p:TreatWarningsAsErrors=true'
See analyzers.md for detailed analyzer configurations.
yaml
- task: DotNetCoreCLI@2
  displayName: 'Build with Analysis'
  inputs:
    command: build
    arguments: '/p:TreatWarningsAsErrors=true'
详细的分析器配置请查看 analyzers.md