dotnet / dotnet/roslyn

Optimize simple IFs as ternary with TUples

Open
#82,644 6 comments 0 reactions 0 assignees View on GitHub
Area-IDE Feature Request
Dominant language
C#
Stars
20.7k
Forks
4.3k
PR merge metrics
PR metrics pending

Description

**Brief description:**

I would appreciate to transform more `if`s into ternaries when the condition are simple enough.

**Languages applicable:**

I think it is mainly C#, but VB may benefit from this aswell?

**Code example that the analyzer should report:**

Original code snippet to replace:
```cs
private string GetStringValueFromFile(string section, string variable, string defaultValue)
{
string toReturn;
string defaultvalue = "Read value:";
string value = GetValue(section, variable); // Reads from external file
if (!string.IsNullOrWhiteSpace(value))
toReturn = value;
else
{
defaultvalue = "Set by default value :";
toReturn = defaultValue;
}
Log.Write("LogHelper", $"{nameof(GetStringValueFromFile)}: {variable}, {defaultValue}, {value}");

return toReturn;
}
```

**Additional information:**

Optimization in 3 steps (manually done here).
Unpacking the branches (defaultValue gets its allocation moved in the relevant branch):
```cs
private string GetStringValueFromFile(string section, string variable, string defaultValue)
{
string toReturn;
string defaultvalue;
string value = GetValue(section, variable); // Reads from external file
if (!string.IsNullOrWhiteSpace(value))
{
defaultvalue = "Read value:";
toReturn = value;
}
else
{
defaultvalue = "Set by default value :";
toReturn = defaultValue;
}
Log.Write("LogHelper", $"{nameof(GetStringValueFromFile)}: {variable}, {defaultValue}, {value}");

return toReturn;
}
```

TUplify the branches (allocation of both strings in one line):
```cs
private string GetStringValueFromFile(string section, string variable, string defaultValue)
{
string toReturn;
string defaultvalue;
string value = GetValue(section, variable); // Reads from external file
if (!string.IsNullOrWhiteSpace(value))
{
(defaultvalue, toReturn) = ("Read value:", value);
}
else
{
(defaultvalue, toReturn) = ("Set by default value :", defaultValue);
}
Log.Write("LogHelper", $"{nameof(GetStringValueFromFile)}: {variable}, {defaultValue}, {value}");

return toReturn;
}
```

Ternarify the branches (same as current ternaries, but applied to an extended case):
```cs
private string GetStringValueFromFile(string section, string variable, string defaultValue)
{
string value = GetValue(section, variable); // Reads from external file
(string defaultvalue, string toReturn) = (!string.IsNullOrWhiteSpace(value)) ? ("Read value:", value) : ("Set by default value :", defaultValue);
Log.Write("LogHelper", $"{nameof(GetStringValueFromFile)}: {variable}, {defaultValue}, {value}");

return toReturn;
}
```

**Documentation requirements:**

When this analyzer is implemented, it must be documented by following the steps at [Documentation for IDE CodeStyle analyzers](https://github.com/dotnet/roslyn/blob/main/docs/contributing/Documentation%20for%20IDE%20CodeStyle%20analyzers.md).

Contributor guide

Open the contributing guide

Research direction

Start by comparing the three transformation steps and the C# example in the issue, then read the linked Documentation for IDE CodeStyle analyzers guidance. Define the supported simple-IF cases and completion criteria before implementing the analyzer; document it according to the referenced Roslyn requirements.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.