Equals on collections¶
ID: cs/equals-on-arraysKind: problemSecurity severity: Severity: recommendationPrecision: highTags: - quality - reliability - correctnessQuery suites: - csharp-security-and-quality.qls
Click to see the query in the CodeQL repository
There are some circumstances where you want to compare two arrays or collections using reference equality, but often you will want a deep comparison instead (that is, one that compares two collections on an element-by-element basis).
Recommendation¶
If you intended to make a deep comparison then the solution depends on whether or not you are using C# 3.5 or later. From C# 3.5 onward LINQ is available and you can replace the call toEquals with a call to the LINQ extension methodSequenceEqual. If this is not possible then you can implement a helper function to compare arrays, which can then be used throughout your code.
Example¶
This example outputs “False” because callingEquals on an array only does a reference comparison.
classEqualsArray{publicstaticvoidMain(string[]args){string[]strings={"hello","world"};string[]moreStrings={"hello","world"};Console.WriteLine(strings.Equals(moreStrings));}}
The following example outputs “True” twice and uses two different methods of performing a deep comparison of the array.
classEqualsArrayFix{staticboolDeepEquals<T>(T[]arr1,T[]arr2){// If arr1 and arr2 refer to the same array, they are trivially equal.if(ReferenceEquals(arr1,arr2))returntrue;// If either arr1 or arr2 is null and they are not both null (see the previous// check), they are not equal.if(arr1==null||arr2==null)returnfalse;// If both arrays are non-null but have different lengths, they are not equal.if(arr1.Length!=arr2.Length)returnfalse;// Failing which, do an element-by-element compare.for(inti=0;i<arr1.Length;++i){// Early out if we find corresponding array elements that are not equal.if(!arr1[i].Equals(arr2[i]))returnfalse;}// If we get here, all of the corresponding array elements were equal, so the// arrays are equal.returntrue;}publicstaticvoidMain(string[]args){string[]strings={"hello","world"};string[]moreStrings={"hello","world"};Console.WriteLine(strings.SequenceEqual(moreStrings));Console.WriteLine(DeepEquals(strings,moreStrings));}}