集合上的相等性¶
ID: cs/equals-on-arrays
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- reliability
- correctness
Query suites:
- csharp-security-and-quality.qls
在某些情况下,您希望使用引用相等性比较两个数组或集合,但通常您需要进行深度比较(即,逐个元素地比较两个集合)。
建议¶
如果您打算进行深度比较,则解决方案取决于您是否使用的是 C# 3.5 或更高版本。从 C# 3.5 开始,可以使用 LINQ,您可以将对 Equals
的调用替换为对 LINQ 扩展方法 SequenceEqual
的调用。如果无法做到这一点,则可以实现一个辅助函数来比较数组,然后可以在整个代码中使用该函数。
示例¶
此示例输出“False”,因为对数组调用 Equals
只会执行引用比较。
class EqualsArray
{
public static void Main(string[] args)
{
string[] strings = { "hello", "world" };
string[] moreStrings = { "hello", "world" };
Console.WriteLine(strings.Equals(moreStrings));
}
}
以下示例输出两次“True”,并使用两种不同的方法对数组执行深度比较。
class EqualsArrayFix
{
static bool DeepEquals<T>(T[] arr1, T[] arr2)
{
// If arr1 and arr2 refer to the same array, they are trivially equal.
if (ReferenceEquals(arr1, arr2)) return true;
// 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) return false;
// If both arrays are non-null but have different lengths, they are not equal.
if (arr1.Length != arr2.Length) return false;
// Failing which, do an element-by-element compare.
for (int i = 0; i < arr1.Length; ++i)
{
// Early out if we find corresponding array elements that are not equal.
if (!arr1[i].Equals(arr2[i])) return false;
}
// If we get here, all of the corresponding array elements were equal, so the
// arrays are equal.
return true;
}
public static void Main(string[] args)
{
string[] strings = { "hello", "world" };
string[] moreStrings = { "hello", "world" };
Console.WriteLine(strings.SequenceEqual(moreStrings));
Console.WriteLine(DeepEquals(strings, moreStrings));
}
}