从 .NET 10 开始,这两种扩展方法 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<TSource> 已过时。 请改用 IComparer<TKey> 新添加的重载。
在代码中调用这些旧的扩展方法会在编译时生成警告 SYSLIB0061 ,通常在运行时生成警告 IndexOutOfRangeException 。
过时的原因
使用类型参数的IComparer<T>? comparer泛型类型TSource错误地实现了原始MaxBy表达式参数和MinBy接受IComparer<T>? comparer表达式参数。 这是不正确的,因为传递给 Comparer<T>.Compare(T, T) 方法的值是由 Expression<Func<TSource, TKey>> keySelector 表达式参数选择的,因此提取的值是泛型类型 TKey。
注释
这以前仅在实际TKey具有相同的构造类型时才TSource起作用。 如果类型是不同的,则运行时 IndexOutOfRangeException:索引在数组边界之外 。将引发,因为找不到所需的扩展方法 IQueryable<TSource> source (例如在中 MaxBy)。
解决方法
使用新添加 MaxBy 的方法或 MinBy 接受 IComparer<TKey>? comparer 参数的方法。 这些不会引发异常。
例如:
// 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,可以在代码或项目文件中禁止显示警告。
若要仅取消单个冲突,请将预处理器指令添加到源文件以禁用,然后重新启用警告。
// 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>
有关详细信息,请参阅 “禁止显示警告”。