var recordValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var sourceField in newItemSmokeTestFieldSet.SourceFields)
{
recordValues.Add(sourceField.Name, $"{sourceField.Name}_Data{recordIndex}");
}
This is aligned with the examples of compliant given for S3267 and there would not be any readability gains by changing this around to be something like
var recordValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var sourceFieldName in newItemSmokeTestFieldSet.SourceFields.Select(sf => sf.Name)
{
recordValues.Add(sourceFieldName, $"{sourceFieldName}_Data{recordIndex}");
}
I think that would cause the allocation of an additional array to hold the source field names to iterate. Please address this
And - to make sure you’re seeing the latest implementation of the rule - what SonarLint version are you using? And if you’re in connected mode, what version of SonarQube, or is it SonarCloud?
you mentioned two aspects, which you would like to see addressed:
No readability gains
What the rule complains about specifically is the access of sourceField.Name (it’s accessed twice) in your example. The idea is that you only want to access a small part of “SourceField” in the loop and you should “Select” what you are interested in outside the loop.
Because Select(sf => sf.Name) accesses the name property only once, the equivalent code would look more like this:
foreach (var sourceField in newItemSmokeTestFieldSet.SourceFields)
{
var sourceFieldName = sourceField.Name;
recordValues.Add(sourceFieldName, $"{sourceFieldName}_Data{recordIndex}");
}
You save one line of code with the Select. I would consider your example an edge case with respect to readability because you gain just a little but it is in the spirit of the rule.
Allocation of an additional array
The short answer is: There is no array allocation caused by Select.
The long answer is, that there is an allocation of a delegate Func<SourceField, string> and of an IEnumerator<string> but there is no array allocation. You can see what is generated behind the scenes on sharplab. The allocations caused by LINQ are a known downside over procedural code but (almost always) neglectable.
I can not see what we can do on our side as the rule behaves as expected. You can use the supression mechanisms to silence the rule or disable the rule in your SonarCube quality profile if you object to the rule in general.