dotnet / roslyn-analyzers

MIT License
1.59k stars 465 forks source link

CA1861: Avoid constant arrays improvements #7001

Open Youssef1313 opened 1 year ago

Youssef1313 commented 1 year ago
mavasani commented 1 year ago

@buyaa-n @carlossanlop for further triage.

manfred-brands commented 4 months ago

I agree with the first point, in IL the code generated for the following three statements is the same, but only the explicit one gets an CA1861 warning. I know the last one is reported in #7090

string trimName1 = name.Trim('.', ',', ';', ' ');
string trimName2 = name.Trim(new[] { '.', ',', ';', ' ' });
string trimName3 = name.Trim(['.', ',', ';', ' ']);

An example for the 2nd point where the array creation does not trigger CA1861 because the members are not literals.

const char dot = '.';
const char comma = ',';
const char semicolon = ';';
const char space = ' ';

string trimName4 = name.Trim(new[] { dot, comma, semicolon, space });
manfred-brands commented 4 months ago

@mavasani If you agree, I'm willing to create a PR for the above.

manfred-brands commented 4 months ago

I'm not sure if you want to put it in this improvement ticket, but I just did a review where someone changed the in-line array creation to creating a local and referencing that one:

string[] parts = line.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

into

char[] separators = new[] { ',', ';' };
string[] parts = line.Split(separators, StringSplitOptions.RemoveEmptyEntries);

This will generate the same IL code. Should CA1861 also trigger when the parameter is a local created from constants?

steveberdy commented 4 months ago

@manfred-brands I see slightly different IL code for both of those code snippets

manfred-brands commented 4 months ago

@steveberdy The differences I see are

Both however create a new array purely for the method which is the point CA1861 tries to address.

steveberdy commented 2 months ago

Should CA1861 also trigger when the parameter is a local created from constants?

When I was creating the analyzer, we discussed that there could be potential cases where the array was mutated after being passed as an argument. In the case of the array being a local, the odds are higher for it being mutated.

I think this is out of the scope of the analyzer. In general, constant, un-mutated locals would be better off as static readonly (generally speaking, but not always), so perhaps that would warrant a separate analyzer. With CA1861, it's really a different analysis since we're dealing with a direct argument that we know is an array of constants.