Udostępnij przez


SYSLIB0061: Element System.Linq.Queryable.MaxBy i System.Linq.Queryable.MinBy biorące element IComparer<TSource> są przestarzałe

Począwszy od platformy .NET 10, dwie metody System.Linq.Queryable.MaxBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) rozszerzenia i System.Linq.Queryable.MinBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>) akceptujące IComparer<TSource> element są przestarzałe. Użyj nowo dodanych przeciążeń, które akceptują zamiast tego IComparer<TKey> .

Wywołanie tych starych metod rozszerzenia w kodzie generuje ostrzeżenie SYSLIB0061 w czasie kompilacji i zwykle generuje element IndexOutOfRangeException w czasie wykonywania.

Przyczyna wycofania z użycia

Oryginalny MaxBy i akceptujący IComparer<T>? comparer parametr wyrażenia został niepoprawnie zaimplementowany przy użyciu typu TSource ogólnego dla parametru IComparer<T>? comparerMinBy typu. Jest to niepoprawne, ponieważ wartości przekazane do Comparer<T>.Compare(T, T) metody są wybierane przez Expression<Func<TSource, TKey>> keySelector parametr wyrażenia, dlatego wyodrębniona wartość jest typu TKeyogólnego .

Uwaga

To wcześniej działało tylko wtedy, gdy TSource i TKey były rzeczywiście tym samym typem skonstruowanym. Jeśli typy były odrębne, środowisko uruchomieniowe IndexOutOfRangeException: Indeks znajdował się poza granicami tablicy. Zostanie zgłoszony, ponieważ nie można odnaleźć wymaganej metody IQueryable<TSource> source rozszerzenia (na przykład w MaxBypliku ).

Rozwiązanie

Użyj nowo dodanej MaxBy metody lub MinBy , która akceptuje IComparer<TKey>? comparer parametr. Nie będą one zgłaszać wyjątku.

Na przykład:

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

Pomijanie ostrzeżenia

Jeśli musisz użyć przestarzałego interfejsu API, możesz pominąć ostrzeżenie w kodzie lub w pliku projektu.

Aby pominąć tylko jedno naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć ostrzeżenie.

// Disable the warning.
#pragma warning disable SYSLIB0061

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

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

Aby pominąć wszystkie ostrzeżenia SYSLIB0061 w projekcie, dodaj właściwość <NoWarn> do pliku projektu.

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

Aby uzyskać więcej informacji, zobacz Pomijanie ostrzeżeń.