|
| 1 | +--- |
| 2 | +title: SYSLIB0061 warning - System.Linq.Queryable.MaxBy and System.Linq.Queryable.MinBy accepting an IComparer\<TSource\> are obsolete. |
| 3 | +description: Learn about the obsoletion of some MaxBy and MinBy extension methods. Use of these extension methods generates compile-time warning SYSLIB0061. |
| 4 | +ms.date: 03/31/2025 |
| 5 | +f1_keywords: |
| 6 | + - SYSLIB0061 |
| 7 | +--- |
| 8 | +# SYSLIB0061: System.Linq.Queryable.MaxBy and System.Linq.Queryable.MinBy taking an IComparer\<TSource\> are obsolete. |
| 9 | + |
| 10 | +Starting in .NET 10, the two extension methods <xref:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0})?displayProperty=fullName> and <xref:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0})?displayProperty=fullName> that accept an `IComparer<TSource>` are obsolete. Please use the newly added overloads that accept an `IComparer<TKey>` instead. |
| 11 | + |
| 12 | +Calling these old extension methods in code generates warning `SYSLIB0061` at compile time and typically generates a <xref:System.IndexOutOfRangeException?displayName=nameWithType> at runtime. |
| 13 | + |
| 14 | +## Reason for obsoletion |
| 15 | + |
| 16 | +The original `MaxBy` and `MinBy` accepting an `IComparer<T>? comparer` expression parameter were incorrectly implemented using the generic type `TSource` for the `IComparer<T>? comparer` type parameter. This is incorrect because the values passed to the <xref:System.Collections.Generic.Comparer`1.Compare(`0,`0)?displayProperty=nameWithType> method are selected by the `Expression<Func<TSource, TKey>> keySelector` expression parameter, thus the extracted value is of generic type `TKey`. |
| 17 | + |
| 18 | +### Note |
| 19 | + |
| 20 | +This would previously work only if `TSource` and `TKey` were actually the same constructed type. If the types were distinct then a runtime _<xref:System.IndexOutOfRangeException>: Index was outside the bounds of the array._ would be thrown because the needed extension method for `IQueryable<TSource> source` could not be found (for example in <xref:System.Linq.Enumerable.MaxBy*>). |
| 21 | + |
| 22 | +## Workaround |
| 23 | + |
| 24 | +Use the newly added `MaxBy` or `MinBy` method that accepts an `IComparer<TKey>? comparer` parameter. These will not throw an exception. |
| 25 | + |
| 26 | +For example: |
| 27 | + |
| 28 | +```csharp |
| 29 | +// This worked correctly since TKey and TSource are both int. |
| 30 | +Enumerable.Range(1, 10) |
| 31 | + .AsQueryable() |
| 32 | + .MaxBy(key => (0 - key), Comparer<int>.Default); |
| 33 | + |
| 34 | +// This would throw since TKey is string but TSource is int |
| 35 | +// and will trigger the obsoletion warning now and would |
| 36 | +// throw an exeception at runtime. |
| 37 | +Enumerable.Range(1, 10) |
| 38 | + .AsQueryable() |
| 39 | + .MaxBy(key => key.ToString(), Comparer<int>.Default); |
| 40 | + |
| 41 | +// This previously would not compile before to the addition of |
| 42 | +// the new methods since TKey is string and TSource is int. |
| 43 | +// It will now compile and execute correctly. |
| 44 | +Enumerable.Range(1, 10) |
| 45 | + .AsQueryable() |
| 46 | + .MaxBy(key => key.ToString(), Comparer<string>.Default); |
| 47 | +``` |
| 48 | + |
| 49 | +## Suppress a warning |
| 50 | + |
| 51 | +If you must use the obsolete API, you can suppress the warning in code or in your project file. |
| 52 | + |
| 53 | +To suppress only a single violation, add preprocessor directives to your source file to disable and then re-enable the warning. |
| 54 | + |
| 55 | +```csharp |
| 56 | +// Disable the warning. |
| 57 | +#pragma warning disable SYSLIB0061 |
| 58 | + |
| 59 | +// Code that uses obsolete API. |
| 60 | +// ... |
| 61 | +
|
| 62 | +// Re-enable the warning. |
| 63 | +#pragma warning restore SYSLIB0061 |
| 64 | +``` |
| 65 | + |
| 66 | +To suppress all the `SYSLIB0061` warnings in your project, add a `<NoWarn>` property to your project file. |
| 67 | + |
| 68 | +```xml |
| 69 | +<Project Sdk="Microsoft.NET.Sdk"> |
| 70 | + <PropertyGroup> |
| 71 | + ... |
| 72 | + <NoWarn>$(NoWarn);SYSLIB0061</NoWarn> |
| 73 | + </PropertyGroup> |
| 74 | +</Project> |
| 75 | +``` |
| 76 | + |
| 77 | +For more information, see [Suppress warnings](obsoletions-overview.md#suppress-warnings). |
0 commit comments