2017-01-30 45 views
0

我有一个类用来定义/保存一个矩形。获取/设置数组属性的元素

我有2个数组包含4个点。一个数组用于保存在文件中的点,另一个用于实际显示的点(可由用户修改)。

我想为保存点的数组中的元素创建一个get/set。当我保存一个点时,它会自动复制到第二个数组中。

我不知道是很清楚,有我想要创建的代码:像这样来使用

public class MyRectangle 
{ 
    public PointF[] TemporaryPoints = new PointF[4]; 

    protected PointF[] _savedPoints = new PointF[4]; 
    protected PointF[] SavedPoints; 

    //How to do something like this ? 
    protected PointF SavedPoints[int i] 
    { 
     get 
     { 
      return _savedPoints[i]; 
     } 
     set 
     { 
      _savedPoints[i] = value; 
      TemporaryPoints[i] = value; 
     } 
    } 
} 

SavedPoints[0] = new PointF(1,1);  // SavedPoints = [1;1] TemporaryPoints = [1;1] 
TemporaryPoints[0] = new PointF(4,4); // SavedPoints = [1;1] TemporaryPoints = [4;4] 
SavedPoints[0] = TemporaryPoints[0]; // SavedPoints = [4;4] TemporaryPoints = [4;4] 
+0

要设置TemporaryPoints [i] =值;以及 – CodeConstruct

回答

1

命名索引是不可能在C#。您可以使用索引语法:

public class MyRectangle 
{ 
    public PointF[] TemporaryPoints = new PointF[4]; 

    protected PointF[] _savedPoints = new PointF[4]; 

    protected PointF this[int i] 
    { 
     get 
     { 
      return _savedPoints[i]; 
     } 
     set 
     { 
      _savedPoints[i] = value; 
      TemporaryPoints[i] = value; 
     } 
    } 
} 

这不给你一个选择的名称SavedPoints访问索引属性。如果你想这样做,你必须创建一个自定义集合SavedPointsCollection来封装这个功能。然后您可以定义该类型的SavedPoints属性。如有必要,您还可以创建一个TemporaryPintsCollection,由SavedPointsCollection访问。

要实现自定义集合,你可以重写System.Collections.ObjectModel.Collection<T>或实现IList<T>接口。 Collection<T>当您想要为项目类型使用标准集合时很好。当您想要做更多花式功能时,可以使用IList<T>作为固定大小的集合。

下面是用(不完全)IList<T>上实施的实例:您想

public class SavedPointsCollection : IList<PointF> { 
    protected PointF[] _values = new PointF[4]; 

    public PointF this[int index] { 
     get 
     { 
      return _values[index]; 
     } 
     set 
     { 
      _values[index] = value; 
      //Set temporary points here 
     } 
    } 

    //Rest of the IList implementation 
} 


public class MyRectangle 
{ 
    private SavedPointsCollection _savedPoints = new SavedPointsCollection(); 

    protected SavedPointsCollection SavedPoints 
    { 
     get { 
      return _savedPoints; 
     } 
    } 
} 
+0

我可以做我想要的。但是我可以定义'this [int i]'一次,所以我不能为最终的第三个数组创建2个索引器? –

+0

@ A.Pissicat:不,你不能有多个索引器。您需要将集合用作属性类型。 – Sefe

0

不是绝对清楚什么,但你可以使用一个索引:

protected PointF this[int index] // Indexer declaration 
{ 
    get 
    { 
     return _savedPoints[index]; 
    } 
    set 
    { 
     _savedPoints[index] = value; 
     TemporaryPoints[index] = value; 
    } 
} 

那么你可以这样做:

var rect = new MyRectangle(); 
rect[0] = new PointF (1,1); 
0

如果你想要做这样的事情,你可以覆盖this[]索引器属性,但您应该创建一个属性TemporaryPoints而不是将其设置为public field。这些可以结合到这样创造的东西:

public class MyRectangle 
{ 
    private PointF[] _temporaryPoints = new PointF[4]; 
    protected PointF[] _savedPoints = new PointF[4]; 

    // get TemporaryPoint by it's index 
    public PointF TemporaryPoint(int idx) 
    { 
     return (idx < _temporaryPoints.Length ? _temporaryPoints[idx] : default(PointF)); 
    } 

    // set TemporaryPoint value at index idx 
    public void SetTemporaryPoint(int idx, PointF value) 
    { 
     if(idx < _temporaryPoints.Length) _temporaryPoints[idx] = value; 
    } 

    // get SavedPoint by it's index 
    public PointF SavedPoint(int idx) 
    { 
     return (idx < _savedPoints.Length ? _savedPoints[idx] : default(PointF)); 
    }  

    // set SavedPoint value at index idx 
    public void SetSavedPoint(int idx, PointF value) 
    { 
     if(idx < _savedPoints.Length) _savedPoints[idx] = value; 
    } 

    //How to do something like this ? 
    protected PointF this[int idx] 
    { 
     get 
     { 
      return SavedPoint(idx); 
     } 
     set 
     { 
      SetSavedPoint(i, value); 
      SetTemporaryPoint(i, value); 
     } 
    } 
} 

既然你不能越权“属性的索引器属性”你应该做的界面,允许您设置只对特定的指数值。 这就是为什么有这种方法:SetTemporaryPoint(int idx, PointF value)。 毕竟,你可以用它几乎一样的,你想要的是:

SetSavedPoint(0, new PointF(1,1));  // SavedPoints = [1;1] TemporaryPoints = [1;1] 
SetTemporaryPoint(0, new PointF(4,4)); // SavedPoints = [1;1] TemporaryPoints = [4;4] 
SetSavedPoint(0, TemporaryPoint(0)); // SavedPoints = [4;4] TemporaryPoints = [4;4] 

但是,如果你真的到只使用this[]索引属性。你可以做一些列举:

public enum POINTS_STORAGE { TEMPORARY = 0, SAVED = 1 }; 

然后在你this[]索引器属性:

public PointF this[POINTS_STORAGE s, int idx] 
{ 
    get 
    { 
     if(s == POINTS_STORAGE.TEMPORARY) 
      return _temporaryPoints[idx]; 
     else 
      return _savedPoints[idx]; 
    } 

    set 
    { 
     if(s == POINTS_STORAGE.TEMPORARY) 
      _temporaryPoints[idx] = value; 
     else 
      _savedPoints[idx] = value; 
    } 
} 

然后你可以使用它像:

meRectangleReference[POINTS_STORAGE.SAVED, 0] = new PointF(1, 1);  // SavedPoints = [1;1] TemporaryPoints = [1;1] 
meRectangleReference[POINTS_STORAGE.TEMPORARY, 0] = new PointF(4,4); // SavedPoints = [1;1] TemporaryPoints = [4;4] 
meRectangleReference[POINTS_STORAGE.SAVED, 0] = meRectangleReference[POINTS_STORAGE.TEMPORARY, 0]; // SavedPoints = [4;4] TemporaryPoints = [4;4]