2009-12-02 72 views
0

我在C#中編寫一個Vector類,並覺得索引器會是一個很好的補充。我是否需要擔心索引超出範圍?使用C#索引器時的索引安全性?

也許代碼示例會更清楚:

class Vector3f 
    { 
     public Vector3f(float x, float y, float z) 
     { 
      this.X = x; 
      this.Y = y; 
      this.Z = z; 
     } 

     public float X {get; set;} 
     public float Y {get; set;} 
     public float Z {get; set;} 

     public float this[int pos] 
     { 
      get 
      { 
       switch (pos) 
       { 
        case 0: return this.X; break; 
        case 1: return this.Y; break; 
        case 2: return this.Z; break; 
       } 
      } 
      set 
      { 
       switch (pos) 
       { 
        case 0: this.X = value; break; 
        case 1: this.Y = value; break; 
        case 2: this.Z = value; break; 
       } 
      } 
     } 
    } 

我應該把default情況下,我switch報表?它應該做什麼?

編輯:這是一個相當愚蠢的問題。如果沒有default的情況,上面的代碼甚至不會編譯。再加上傑森在下面的實施非常棒。

回答

7

這是更清晰,避免了需要擔心範圍檢查:

public enum Coordinate { X, Y, Z } 
public float this[Coordinate coordinate] { 
    get { 
     switch(coordinate) { 
      case Coordinate.X: return this.X; 
      case Coordinate.Y: return this.Y; 
      case Coordinate.Z: return this.Z; 
      // convince the compiler that we covered everything 
      default: throw new ArgumentOutOfRangeException("coordinate"); 
     } 
    } 
    set { 
     switch(coordinate) { 
      case Coordinate.X: this.X = value; break; 
      case Coordinate.Y: this.Y = value; break; 
      case Coordinate.Z: this.Z = value; break; 
     } 
    } 
} 

但是請注意,座標是已經公開的,有啥索引的地步?

+1

這很漂亮。 – Anton 2009-12-02 02:37:39

+0

如果需要,索引器可以更容易地遍歷Vector的座標。 – mkenyon 2009-12-02 02:38:57

+1

偉大的實施。 – Alex 2009-12-02 02:39:13

1

我想你應該像其他容器(如List)一樣拋出ArgumentOutOfRangeException。 你可以從默認情況下拋出它。

0

也許你應該使用枚舉而不是int索引器,這樣,你的代碼會更清晰,你不必擔心超出範圍的錯誤。事實上,你讓人們很難看到代碼的意圖。

無論如何,你需要什麼索引器,爲什麼有人會使用vector [0]而不是vector.X?

+0

使用索引器可以更容易地遍歷Vector。枚舉是一個好主意! – mkenyon 2009-12-02 02:38:24

0

如果指數不一定必須是整數,您能介紹枚舉,所以編譯器將保證沒有無效的選擇是在代碼中的任何地方使用。