LINQBridge IComparer exception

本文关键字:exception IComparer LINQBridge | 更新日期: 2023-09-27 18:16:46

我正在使用针对。net 2.0框架的LINQ Bridge,并且我得到以下错误。只需要从集合中随机选择的第一个元素。在这种特殊情况下不关心性能。

var result = someCollection.OrderBy(g => Guid.NewGuid()).Take(1).FirstOrDefault();

someecollection是一个List<string>。集合中的值是唯一的。

无法排序,因为IComparer.Compare()方法返回不一致的结果。要么一个值不等于它本身,或者一个值与另一个值反复比较产生不同的结果结果。x: ", x's type: 'Tuple 2', IComparer: 'System.Array+FunctorComparer 1[LinqBridge.Tuple ' 2[System.String,System.Int32]]'.

但是它似乎在。net 4.0中工作得很好。有解决这个问题的方法吗?不幸的是,对于这种情况,我只能使用。net 2.0。

EDIT使用最新版本的LINQ Bridge (1.2)

LINQBridge IComparer exception

又一次更新

我发现这个问题和你有同样的问题:为什么在排序中使用随机导致[无法对比较器排序。比较误差)
问题是LINQBridge在内部使用List<>.Sort,当使用"不稳定"的比较算法时,它会抱怨,所以你不幸的是不能随机化这种方式。

作为替代方案,这里有一些很好的代码来随机化或选择一个随机项:

    private static Random rnd = new Random();
    /// <summary>
    /// Chooses one of the items at random.
    /// 
    /// Returns default if there are no items.
    /// </summary>
    public static T RandomOrDefault<T>(this IEnumerable<T> source)
    {
        // We need the count:
        var buffer = source as ICollection<T> ?? source.ToList(); // (iterate only once)
        var itemCount = buffer.Count;
        if (itemCount == 0)
        {
            return default(T);
        }
        var index = rnd.Next(itemCount);
        return buffer.ElementAt(index);
    }
    /// <summary>
    /// Randomizes the order of the elements of a sequence. 
    /// </summary>
    public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
    {
        // This code is an implementation of the Fisher–Yates shuffle.
        // The code was obtained from:
        // https://stackoverflow.com/questions/1287567/c-is-using-random-and-orderby-a-good-shuffle-algorithm/1665080#1665080
        T[] elements = source.ToArray();
        // Note i > 0 to avoid final pointless iteration
        for (int i = elements.Length - 1; i > 0; i--)
        {
            // Swap element "i" with a random earlier element it (or itself)
            int swapIndex = rnd.Next(i + 1);
            yield return elements[swapIndex];
            elements[swapIndex] = elements[i];
            // we don't actually perform the swap; we can forget about the
            // swapped element because we already returned it.
        }
        // there is one item remaining that was not returned - we return it now
        yield return elements[0];
    }

更新

这个异常看起来真的像是LINQBridge的bug。我建议升级到最新版本。没有其他明显的原因导致你看到这个问题。

附加信息

您可以使用Random代替Guid,如下所示:

var rnd = new Random();
var result = someCollection.OrderBy(g => rnd.Next()).Take(1).FirstOrDefault();

同样,.Take(1).FirstOrDefault()

之后是绝对不必要的。