Skip to content

C# Suggestions

Igor Rončević edited this page Jan 16, 2019 · 3 revisions

To contribute to C# Suggestions check the open issues marked as csharp-suggestion or propose new ones.

C# Suggestions are implemented using Roslyn. If you are new to Roslyn the resources listed on the Awesome Roslyn list should give you a good start.

Before starting developing C# Suggestions make sure to take a look at the existing ones. Your C# Suggestions should follow the same structure and naming conventions as the existing suggestions.

For each suggestion, you have to provide the corresponding smoke tests, both positive and negative. Your smoke tests should follow the same structure and naming conventions as the existing smoke tests.

Implementation Considerations

Performance

In case of real-life, large solutions, the code that implements a single analysis can be called tens of thousands of times, basically once per each C# code file in the solution. Therefore we consider each suggestion implementation to be on a hot path and demand high-performance implementation.

In particular, when implementing suggestions:

  • avoid creating unnecessary objects, especially arrays (lists, strings, ...).
  • prefer node.IsKind(SyntaxKind.XYZ) over node is XYZSyntax.

Structure

Ideally, whenever possible, all suggestion implementations should follow the same structure. They should be implemented as LINQ queries that filter out possible result candidates. The filters should go from less time and resource consuming toward more time and resource consuming.

A suggestion implementation should ideally look like this:

return syntaxTree.GetRoot()
    .DescendantNodes()
    .OfType<XYZSyntax>()
    .Where(node => SomeCondition(node) && SomeOtherCondition(node))
    .Select(node => new AnalysisResult
    (
        ...
    ));

For typical examples, see BaseUseOutVariables.cs or BaseUseExpressionBodyForGetOnlyMembers.cs.

Here are some additional conventions to be followed:

  • For slicing down the logic, use local functions instead of private methods. E.g. the SomeCondition() and the SomeOtherCondition() methods in the above example are local functions within the Analyze() method.