SYSLIB0061: System.Linq.Queryable.MaxBy och System.Linq.Queryable.MinBy som tar en IComparer<TSource> är föråldrade

Från och med .NET 10 är de två tilläggsmetoderna System.Linq.Queryable.MaxBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) och System.Linq.Queryable.MinBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) som accepterar en IComparer<TSource> föråldrade. Använd de nyligen tillagda överlagringarna som accepterar en IComparer<TKey> i stället.

Att anropa dessa gamla tilläggsmetoder i kod genererar vanligtvis en varning SYSLIB0061 vid kompileringstillfället och en IndexOutOfRangeException vid körning.

Orsak till obsoletion

Den ursprungliga MaxBy och MinBy som accepterar en IComparer<T>? comparer-uttrycksparameter implementerades felaktigt med den generiska typen TSource för typparametern IComparer<T>? comparer. Detta är felaktigt eftersom de värden som skickas till metoden väljs av Comparer<T>.Compare(T, T) uttrycksparametern, vilket innebär att Expression<Func<TSource, TKey>> keySelector det extraherade värdet är av allmän typ TKey.

Anmärkning

Detta skulle tidigare bara fungera om TSource och TKey faktiskt var samma konstruerade typ. Om typerna var distinkta skulle ett runtime IndexOutOfRangeException: Index ligga utanför matrisens gränser. skulle genereras eftersom det inte gick att hitta den tilläggsmetod som behövs för IQueryable<TSource> source (till exempel i MaxBy).

Omgångslösning

Använd den nyligen tillagda MaxBy metoden eller MinBy metoden som accepterar en IComparer<TKey>? comparer parameter. Dessa utlöser inte ett undantag.

Till exempel:

// 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);

Undertryck en varning

Om du måste använda det föråldrade API:et kan du utelämna varningen i koden eller i projektfilen.

Om du bara vill förhindra en enda överträdelse lägger du till förprocessordirektiv i källfilen för att inaktivera och återaktiverar sedan varningen.

// Disable the warning.
#pragma warning disable SYSLIB0061

// Code that uses obsolete API.
// ...

// Re-enable the warning.
#pragma warning restore SYSLIB0061

Om du vill ignorera alla SYSLIB0061 varningar i projektet lägger du till en <NoWarn>-egenskap i projektfilen.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
   ...
   <NoWarn>$(NoWarn);SYSLIB0061</NoWarn>
  </PropertyGroup>
</Project>

För mer information, se Undertrycka varningar.