diff --git a/src/libraries/System.Linq/tests/OfTypeTests.cs b/src/libraries/System.Linq/tests/OfTypeTests.cs index 9c4464f2bf6ce0..9fcfdd8efeb82b 100644 --- a/src/libraries/System.Linq/tests/OfTypeTests.cs +++ b/src/libraries/System.Linq/tests/OfTypeTests.cs @@ -228,5 +228,35 @@ public void MultipleIterations() Assert.Equal(i + 1, count); } } + + [Fact] + public void MultiDimArray_OfType_Succeeds() + { + var array = new string[3, 4]; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + array[i, j] = $"{i}{j}"; + } + } + + // ToArray + var result = array.OfType().ToArray(); + Assert.Equal(12, result.Length); + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + Assert.Equal($"{i}{j}", result[i * 4 + j]); + } + } + + // Contains + foreach (string s in array) + { + Assert.True(array.OfType().Contains(s)); + } + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index a98f5b0256c122..c1157d432be238 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -1039,7 +1039,22 @@ int IList.Add(object? value) bool IList.Contains(object? value) { - return IndexOf(this, value) >= this.GetLowerBound(0); + // IndexOf only works for single-dimensional arrays. + if (Rank == 1) + { + return IndexOf(this, value) >= GetLowerBound(0); + } + + // For multi-dimensional arrays, fall back to enumeration. + foreach (object? element in this) + { + if (Equals(element, value)) + { + return true; + } + } + + return false; } void IList.Clear() diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs index 96856a698c8888..db98f2fb37ee9f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs @@ -81,7 +81,7 @@ public static void CastAs_IListOfT() [Fact] public static void Construction() { - // Check a number of the simple APIs on Array for dimensions up to 4. + // Check a number of the simple APIs on Array for dimensions up to 4, first with value types, then reference types. Array array = new int[] { 1, 2, 3 }; VerifyArray(array, typeof(int), new int[] { 3 }, new int[1]); @@ -93,6 +93,18 @@ public static void Construction() array = new int[2, 3, 4, 5]; VerifyArray(array, typeof(int), new int[] { 2, 3, 4, 5 }, new int[4]); + + array = new string[] { "1", "2", "3" }; + VerifyArray(array, typeof(string), new int[] { 3 }, new int[1]); + + array = new string[,] { { "1", "2", "3" }, { "4", null, "6" } }; + VerifyArray(array, typeof(string), new int[] { 2, 3 }, new int[2]); + + array = new string[2, 3, 4]; + VerifyArray(array, typeof(string), new int[] { 2, 3, 4 }, new int[3]); + + array = new string[2, 3, 4, 5]; + VerifyArray(array, typeof(string), new int[] { 2, 3, 4, 5 }, new int[4]); } [Fact] @@ -4682,10 +4694,19 @@ private static void VerifyArrayAsIList(Array array) } else { - Assert.Throws(() => iList.Contains(null)); Assert.Throws(() => iList.IndexOf(null)); AssertExtensions.Throws(null, () => iList[0]); AssertExtensions.Throws(null, () => iList[0] = 1); + + bool containsNull = false; + foreach (object? obj in array) + { + containsNull |= obj is null; + Assert.True(iList.Contains(obj), $"{obj} not found in {string.Join(",", array.Cast())}"); + } + + Assert.False(iList.Contains(new object())); + Assert.Equal(containsNull, iList.Contains(null)); } }