Compartir a través de


SYSLIB0061: System.Linq.Queryable.MaxBy y System.Linq.Queryable.MinBy tomando un TSource> de IComparer<están obsoletos

A partir de .NET 10, los dos métodos System.Linq.Queryable.MaxBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) de extensión y System.Linq.Queryable.MinBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) que aceptan un IComparer<TSource> están obsoletos. Use las sobrecargas recién agregadas que aceptan en IComparer<TKey> su lugar.

Al llamar a estos métodos de extensión antiguos en el código se genera una advertencia SYSLIB0061 en tiempo de compilación y normalmente se genera un IndexOutOfRangeException en tiempo de ejecución.

Motivo de obsolescencia

El original MaxBy y MinBy aceptando un IComparer<T>? comparer parámetro de expresión se implementaron incorrectamente mediante el tipo TSource genérico para el IComparer<T>? comparer parámetro de tipo. Esto es incorrecto porque los valores pasados al Comparer<T>.Compare(T, T) método se seleccionan mediante el Expression<Func<TSource, TKey>> keySelector parámetro de expresión, por lo que el valor extraído es de tipo TKeygenérico .

Nota:

Esto solo funcionaría anteriormente si TSource y TKey fueran realmente el mismo tipo construido. Si los tipos fueran distintos, un runtime IndexOutOfRangeException: index estaba fuera de los límites de la matriz. Se produciría porque no se encontró el método de extensión necesario para IQueryable<TSource> source (por ejemplo, en MaxBy).

Solución

Use el método o MinBy recién agregado MaxBy que acepta un IComparer<TKey>? comparer parámetro. No producirán una excepción.

Por ejemplo:

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

Suprimir una advertencia

Si debe usar la API obsoleta, puede suprimir la advertencia en el código o en el archivo del proyecto.

Para suprimir solo una infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la advertencia.

// Disable the warning.
#pragma warning disable SYSLIB0061

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

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

Para suprimir todas las SYSLIB0061 advertencias del proyecto, agregue una <NoWarn> propiedad al archivo del proyecto.

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

Para obtener más información, vea Suprimir advertencias.