2009-12-02 41 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

如果指数不一定必须是整数,您能介绍枚举,所以编译器将保证没有无效的选择是在代码中的任何地方使用。