Skip to content

LINQ Contains() crashes with System.RankException when used together with a multidimensional array #119569

@Garzuuhl

Description

@Garzuuhl

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}");

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions