次の方法で共有


SYSLIB0061: IComparer<TSource を受け取る System.Linq.Queryable.MaxBy と System.Linq.Queryable.MinBy は廃止されています>

.NET 10 以降では、IComparer<TSource>を受け入れる 2 つの拡張メソッドSystem.Linq.Queryable.MaxBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>)System.Linq.Queryable.MinBy<TSource,TKey>(IQueryable<TSource>, Expression<Func<TSource,TKey>>, IComparer<TSource>)は廃止されています。 代わりに、 IComparer<TKey> を受け入れる新しく追加されたオーバーロードを使用してください。

コードでこれらの古い拡張メソッドを呼び出すと、コンパイル時に警告 SYSLIB0061 が生成され、通常は実行時に IndexOutOfRangeException が生成されます。

難読化の理由

IComparer<T>? comparer式パラメーターを受け入れる元のMaxByMinByが、IComparer<T>? comparer型パラメーターのジェネリック型TSourceを使用して誤って実装されました。 これは、 Comparer<T>.Compare(T, T) メソッドに渡される値が Expression<Func<TSource, TKey>> keySelector 式パラメーターによって選択されるため、抽出された値はジェネリック型の TKeyであるため、正しくありません。

これは、 TSourceTKey が実際に同じ構築型である場合にのみ機能していました。 型が異なる場合、ランタイム IndexOutOfRangeException: Index が配列の範囲外でした。IQueryable<TSource> sourceに必要な拡張メソッドが見つからなかったため (たとえば、MaxByで) スローされます。

対処法

IComparer<TKey>? comparer パラメーターを受け取る新しく追加されたMaxByまたはMinByメソッドを使用します。 これらは例外をスローしません。

例えば次が挙げられます。

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

警告を抑制する

古い API を使用する必要がある場合は、コードまたはプロジェクト ファイルで警告を抑制できます。

1 つの違反のみを抑制するには、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、警告を再度有効にします。

// Disable the warning.
#pragma warning disable SYSLIB0061

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

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

プロジェクト内のすべての SYSLIB0061 警告を抑制するには、プロジェクト ファイルに <NoWarn> プロパティを追加します。

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

詳細については、「警告を 抑制する」を参照してください。