Don’t call loop invariant functions in loop conditions.

Why is this an issue ?

Loop invariant functions do not depend on the current loop iteration, yet they are still evaluated each time. This can lead to performance issues, especially when the loop is executed a large number of times, and/or if the function requires a lot of processing. Instead, consider calling the function once before the loop and caching the result.

Note that property getters are not included in this rule, as they are expected to be fast and side-effect free.

When can it be ignored ?

The analyzer may return false positives when the function call actually has a side effect, despite being syntactically loop invariant. In which case this warning should be ignored.

Non compliant examples

static int getMaxValue() => 10;

for (int i = 0; i < getMaxValue(); i++) // Noncompliant: getMaxValue() is loop invariant
    Console.WriteLine(i);
static int getValue(int n) => n;

int j = 10;
for (int i = 0; i < getValue(j); i++) // Noncompliant: getValue(j) is loop invariant
    Console.WriteLine(i);

Compliant examples

static int getMaxValue() => 10;

int maxValue = getMaxValue();
for (int i = 0; i < maxValue; i++) // Compliant
    Console.WriteLine(i);
static int getValue(int n) => n;

int j = 10;
for (int i = 0; i < getValue(j); i++) { // Compliant: j is mutated in the loop, the call is not loop invariant
        if (i % 2 == 0) j--;
    Console.WriteLine(i);
}