Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Starting in .NET 10, the two extension methods System.Linq.Queryable.MaxBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) and System.Linq.Queryable.MinBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) that accept an IComparer<TSource> are obsolete. Please use the newly added overloads that accept an IComparer<TKey> instead.
Calling these old extension methods in code generates warning SYSLIB0061 at compile time and typically generates a IndexOutOfRangeException at runtime.
Reason for obsoletion
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 Comparer<T>.Compare(T, T) method are selected by the Expression<Func<TSource, TKey>> keySelector expression parameter, thus the extracted value is of generic type TKey.
Note
This would previously work only if TSource and TKey were actually the same constructed type. If the types were distinct then a runtime 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 MaxBy).
Workaround
Use the newly added MaxBy or MinBy method that accepts an IComparer<TKey>? comparer parameter. These will not throw an exception.
For example:
// This worked correctly since TKey and TSource are both int.
Enumerable.Range(1, 10)
    .AsQueryable()
    .MaxBy(key => (0 - key), Comparer<int>.Default);
// This would throw since TKey is string but TSource is int
// and will trigger the obsoletion warning now and would
// throw an exeception at runtime.
Enumerable.Range(1, 10)
    .AsQueryable()
    .MaxBy(key => key.ToString(), Comparer<int>.Default);
// This previously would not compile before to the addition of
// the new methods since TKey is string and TSource is int.
// It will now compile and execute correctly.
Enumerable.Range(1, 10)
    .AsQueryable()
    .MaxBy(key => key.ToString(), Comparer<string>.Default);
Suppress a warning
If you must use the obsolete API, you can suppress the warning in code or in your project file.
To suppress only a single violation, add preprocessor directives to your source file to disable and then re-enable the warning.
// Disable the warning.
#pragma warning disable SYSLIB0061
// Code that uses obsolete API.
// ...
// Re-enable the warning.
#pragma warning restore SYSLIB0061
To suppress all the SYSLIB0061 warnings in your project, add a <NoWarn> property to your project file.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
   ...
   <NoWarn>$(NoWarn);SYSLIB0061</NoWarn>
  </PropertyGroup>
</Project>
For more information, see Suppress warnings.