-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Open
Description
Description
We are using multidimensional arrays in a few places in our codebase. When I tried to upgrade to dotnet 10 RC1 everything build correctly but when I run our tests some failed because of a System.RankException
. After further inspection I could reproduce this error with the steps below
Reproduction Steps
var mArray = new A[,]
{
{ new() { Value = 1 }, new() { Value = 2 } },
{ new() { Value = 3 }, new() { Value = 4 } }
};
var first = mArray[0, 0];
// This call crashes in dotnet 10
var contains = mArray.OfType<A>().Contains(first);
Console.WriteLine($"Contains: {contains}");
public class A
{
public int Value { get; set; }
}
Expected behavior
For Contains()
to not crash and return true
Actual behavior
.OfType<A>().Contains(...)
crashes with a System.RankException
:
System.RankException
HResult=0x80131517
Message=Only single dimension arrays are supported here.
Source=System.Private.CoreLib
StackTrace:
at System.ThrowHelper.ThrowRankException(ExceptionResource resource)
at System.Array.IndexOf(Array array, Object value, Int32 startIndex, Int32 count)
at System.Array.System.Collections.IList.Contains(Object value)
at Program.<Main>$(String[] args) in D:\source\dotnet10\ConsoleApp1\ConsoleApp1\Program.cs:line 13
Regression?
It does work in dotnet 9 and before.
Known Workarounds
Adding .Select(x=>x)
between OfType and Contains seems to fix the problem.
Configuration
No response
Other information
Based on the Workaround it might be a result of #112684, bypassing those optimizations.
It also only seems to be impacting reference types. Following code examples work just fine
Structs:
var mArray = new S[,]
{
{ new(){Value = 1}, new(){Value = 2} },
{ new(){Value = 3}, new(){Value = 4} }
};
var first = mArray[0, 0];
var contains = mArray.OfType<S>().Contains(first, EqualityComparer<S>.Create((s, s2) => s.Value == s2.Value));
Console.WriteLine($"Contains: {contains}");
public struct S
{
public int Value { get; set; }
}
Primitive type (int):
var mArray = new int[,]
{
{ 1, 2 },
{ 3, 4 }
};
var first = mArray[0, 0];
var contains = mArray.OfType<int>().Contains(first);
Console.WriteLine($"Contains: {contains}");