You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

List.RemoveAll结合Lambda表达式异常:误删全部元素求助

问题分析与解决方案

嘿,这个坑我踩过!你遇到的问题根源在于浮点数的精度比较问题,而不是RemoveAll方法本身的逻辑错误。

为什么会误删所有元素?

你的代码里直接用==比较Latitude和Longitude:

y.Position.Latitude == x.Position.Latitude && y.Position.Longitude == x.Position.Longitude

但Latitude和Longitude几乎都是double(或其他浮点类型),这类数值在计算机中是近似存储的——哪怕两个坐标看起来完全一样,底层二进制可能存在极其微小的精度差异(比如1.23456789和1.2345678900000001)。这种差异会导致==的判断结果完全不符合预期,最终让RemoveAll的筛选条件错误地匹配了所有元素,所以才会把整个列表清空。

正确的解决方法

不要直接用==比较浮点类型的坐标,而是判断两个值的差值的绝对值小于一个极小的阈值(比如1e-9,这个值可以根据你的坐标精度需求调整)。

修改后的代码如下:

// 定义一个精度阈值,适配坐标的精度需求
const double precisionThreshold = 1e-9;
listCurrentPostsMarkers.RemoveAll(x => 
    listRemoveMarkers.Exists(y => 
        Math.Abs(y.Position.Latitude - x.Position.Latitude) < precisionThreshold 
        && Math.Abs(y.Position.Longitude - x.Position.Longitude) < precisionThreshold
    )
);

更优雅的优化方案

如果你的项目里经常需要比较坐标,可以封装一个比较器或者重写坐标类的Equals方法,避免重复写精度判断逻辑:

  1. 自定义IEqualityComparer:
public class PositionEqualityComparer : IEqualityComparer<Position>
{
    private readonly double _threshold;

    public PositionEqualityComparer(double threshold = 1e-9)
    {
        _threshold = threshold;
    }

    public bool Equals(Position x, Position y)
    {
        if (x == null || y == null) return x == y;
        return Math.Abs(x.Latitude - y.Latitude) < _threshold 
               && Math.Abs(x.Longitude - y.Longitude) < _threshold;
    }

    public int GetHashCode(Position obj)
    {
        // 根据精度取整后计算哈希,避免精度差异导致哈希值不同
        return HashCode.Combine(
            Math.Round(obj.Latitude, 9), 
            Math.Round(obj.Longitude, 9)
        );
    }
}

使用时的代码会更简洁:

var positionComparer = new PositionEqualityComparer();
listCurrentPostsMarkers.RemoveAll(x => 
    listRemoveMarkers.Any(y => positionComparer.Equals(y.Position, x.Position))
);

内容的提问来源于stack exchange,提问作者fine line

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:43:56