C#List <T> .Find(x => x.Rectangle.Contains(Point))FAIL

One*_*way 3 .net contains point

对于我的生活,我无法理解为什么这段代码会产生以下输出...

我认为当使用List和lambda时,如果类型公开了一个Rectangle属性并使用了矩形对象的Contains方法,那么就会有一个bug或者什么......当List Find方法失败时,显式迭代证明是真的....

单程

public GridSquare WorldToKeyPadSub(Point location)
    {
        location = _Map.WorldToClient(location);
        GridSquare gs = this.Find(x => x.Rectangle.Contains(location));
        GridSquare kp = gs.Find(x => x.Rectangle.Contains(location));
        List<GridSquare> list = kp.FindAll(x=>x.Rectangle.Contains(location));
        u.dp(list.Count);
        GridSquare sub = kp.Find(x => x.Rectangle.Contains(location));

        if (sub == null)
        {
            u.dp("Location to look for " + location);
            u.dp("Found Location in grid square " + gs.ToString());
            u.dp("grid square bounds " + gs.Rectangle.ToString());
            u.dp("Found Location in Keypad " + kp.ToString());
            u.dp("key pad bounds " + kp.Rectangle.ToString());
            u.dp("Sub Key Pads Print All sub keys in this grid.keypad");
            foreach (GridSquare t in kp)
            {
                u.dp(t.ToString() + "  " + t.Rectangle.ToString());                   

            }
            u.dp("Sub Key Pads Print Explicit Finds");
            foreach (GridSquare t in kp)
            {
                if (location.X >= t.Location.X
                    && location.Y >= t.Location.Y
                    && location.X <= t.Location.X + t.Rectangle.Width
                    && location.Y <= t.Location.Y + t.Rectangle.Height)
                {
                    u.dp(true);
                    u.dp(t.ToString() + "  " + t.Rectangle.ToString());
                }

            }
        }
        return sub;
    }
Run Code Online (Sandbox Code Playgroud)

这产生以下输出......

注意显式Rectangle(又名手动方法)如何找到包含位置的网格方格....内部GDI版本失败....

Location to look for {X=1476,Y=1716}
Found Location in grid square GS: 14.3.0.0
grid square bounds {X=1398,Y=1650,Width=100,Height=100}
Found Location in Keypad GS: 14.3.6.0
key pad bounds {X=1465,Y=1683,Width=33,Height=34}
Sub Key Pads Print All sub keys in this grid.keypad
GS: 14.3.6.7  {X=1465,Y=1683,Width=11,Height=11}
GS: 14.3.6.8  {X=1476,Y=1683,Width=11,Height=11}
GS: 14.3.6.9  {X=1487,Y=1683,Width=11,Height=11}
GS: 14.3.6.4  {X=1465,Y=1694,Width=11,Height=11}
GS: 14.3.6.5  {X=1476,Y=1694,Width=11,Height=11}
GS: 14.3.6.6  {X=1487,Y=1694,Width=11,Height=11}
GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}
GS: 14.3.6.3  {X=1487,Y=1705,Width=11,Height=11}
Sub Key Pads Print Explicit Finds
True
GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}
True
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}
A first chance exception of type 'System.NullReferenceException'
Run Code Online (Sandbox Code Playgroud)

Dyn*_*ard 6

Rectangle.Contains(Point) 在矩形的上界是独占的(严格小于).

例如,Rectangle.Contains(Point)在您的上下文中执行的等效检查将是:

foreach (GridSquare t in kp) 
{ 
    if (location.X >= t.Location.X 
        && location.Y >= t.Location.Y 
        && location.X < t.Location.X + t.Rectangle.Width   // < instead of <=
        && location.Y < t.Location.Y + t.Rectangle.Height) // < instead of <=
    { 
        u.dp(true); 
        u.dp(t.ToString() + "  " + t.Rectangle.ToString()); 
    } 

} 
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它将上限验证为严格小于,而不是小于或等于您的方法和Rectangle.Contains(Point)谎言之间的差异.

在你的例子中传递的位置是{X = 1476,Y = 1716},当传递给那些矩形的包含时:

GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}  
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}  
Run Code Online (Sandbox Code Playgroud)

当你的回归真实时,它将返回虚假.

这就是kp.Find(x => x.Rectangle.Contains(location));返回null的原因,但是您的手动检查返回true.