2010-02-04 18 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