gpt4 book ai didi

c# - 由于整数溢出,OrderByDescending 操作不正确

转载 作者:行者123 更新时间:2023-11-30 17:39:27 26 4
gpt4 key购买 nike

在浏览 Enumerable 类的 .Net Framework 源代码时,我发现它的内部 EnumerableSorter 类 CompareKeys method用于排序的有以下一行:

return descending ? -c : c;

其中 cIComparer.Compare Method (T, T) 的结果方法调用,这实际上并不强制我们仅使用 -1、1 或 0 来表示排序。

考虑到 -Int32.MinValue == Int32.MinValue由于整数溢出,它可能导致不正确的排序,如以下代码片段所示:

public class Value : IComparable<Value>
{
private readonly Int32 _value;
public Value(Int32 value)
{
this._value = value;
}

public Int32 CompareTo(Value other)
{
if (other == null)
throw new ArgumentNullException(nameof(other));
var cmp = this._value.CompareTo(other._value);
if (cmp > 0)
return Int32.MaxValue;
if (cmp < 0)
return Int32.MinValue;
return 0;
}

public override String ToString()
{
return this._value.ToString();
}
}

private static void Print<T>(String header, IEnumerable<T> values)
{
Console.WriteLine(header);
foreach (var item in values)
{
Console.WriteLine(item);
}
Console.WriteLine();
}

public static void Main()
{
try
{
var notSorted = new[] { 1, 3, 2 }
.Select(i =>
new Value(i))
.ToArray();

Print("Not sorted", notSorted);
Print("Sorted by", notSorted.OrderBy(item => item));
Print("Sorted by descending", notSorted.OrderByDescending(item => item));
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
Console.WriteLine("Press any key...");
Console.ReadKey(true);
}

对于 OrderByDescending 它产生:

Sorted by descending312

这是预料之中的,但也是一个明显不正确的结果。

所以这似乎是 .Net 中的一个缺陷,但如果 CompareTo 以合理的方式实现则不太可能发生。我说得对吗?

更新:

正如 SLaks 所指出的这个问题早已为人所知,但尽管发布了所有新版本,但仍未得到解决 - https://connect.microsoft.com/VisualStudio/feedback/details/634949/orderbydescending-fails-in-linq-to-objects-when-a-comparer-returns-int-minvalue

正如 usr 所指出的.Net Core 已修复此问题 - https://github.com/dotnet/corefx/blob/35e03c78d89d02f2d3b4a1f8b277a35c88f45750/src/System.Linq/src/System/Linq/OrderedEnumerable.cs#L628

最佳答案

似乎没有多少答案可以做出,所以:

正如 SLaks 所指出的,该问题早已为人所知,但从未在 .NET Framework 中得到修复,尽管有所有新版本(截至目前为 .Net 4.6.1)- https://connect.microsoft.com/VisualStudio/feedback/details/634949/orderbydescending-fails-in-linq-to-objects-when-a-comparer-returns-int-minvalue .

避免此问题的唯一方法是不从 CompareTo 实现中返回 Int32.MinValue


但正如 usr 所指出的那样 .Net Core 已修复此问题 - https://github.com/dotnet/corefx/blob/35e03c78d89d02f2d3b4a1f8b277a35c88f45750/src/System.Linq/src/System/Linq/OrderedEnumerable.cs#L628

关于c# - 由于整数溢出,OrderByDescending 操作不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35537357/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com