2010-02-04 55 views
3

对于我的生活为什么这个代码产生下面的输出,我可以没有任何意义......C#列表<T> .Find(X => x.Rectangle.Contains(点))失败

我想有是一个错误或什么时使用列表和lambda如果类型公开一个Rectangle属性,并且您使用矩形对象的Contains方法...显式迭代证明true,而列表查找方法失败......

单向

代码

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; 
    } 

这将产生以下输出...

通知明确矩形(又名手动方法)如何查找包含位置....中房子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' 

回答

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()); 
    } 

} 

正如你所看到的,它验证,而不是较小的大于或等于,上界为严格大于较小,你的方法和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} 

将返回false,当你将返回true。

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

+0

我想指出这是非法的......我建议使用单声道来源作为参考。 – Dykam 2010-02-04 06:14:24

+1

我想你的观点是可能的,但是我怀疑链接到莫诺的开罗会对没有使用它的人做任何好处。 – 2010-02-04 14:16:46

0

我看到两件事情你可以检查:

  1. 你明确的检查是包容性 - 低于和等号,大于-和平等。如果Rectangle.Contains是独占的,那么你的明确检查点将被省略。

  2. 确定x.Location.X和.Y总是与x.Rectangle.X和.Y相同吗?

2

这是我发现了什么......

考虑一下被定义0,0,100,100矩形...

人们会认为这一点是100,100的里面矩形,但事实并非如此...

Rectangle.Contains不包括边界...换言之,它只会返回true,对于定义的矩形中的所有点0,0到99,99为0,0,100,100 ...

我遇到的麻烦是,当你使用GDI绘制矩形时...像素被绘制偏向下并且正确...

最终结果是Rectangle.Contains包含矩形的顶部和左侧腿,并且对于矩形的底部和右侧腿是独占的......并且从图形角度来看..您可以放大到鼠标点击测试期间的像素级别...

游标可能看起来正好在矩形右边界和下边界之内......但是由于矩形的独有性质,命中测试返回false 。包含右腿和下肢...

SW