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.