Reputation: 3265
I have a class used to define/save a rectangle.
I have 2 array containing 4 Points. One array is for points saved in file, the other one is for points actually display (can be modify by user).
I want to create a get/set for elements in array with saved points. When I save a point, it is automatically copied in second array.
I not sure to be very clear, there is the code I want to create :
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;
}
}
}
Used like this :
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]
Upvotes: 0
Views: 114
Reputation: 14007
Named indexers are not possible in C#. You can use indexer syntax:
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;
}
}
}
That doesn't give you an option to access an indexed property with the name SavedPoints
. If you want to do that you have to create a custom collection SavedPointsCollection
that encapsulates this functionality. You can then define a SavedPoints
property of that type. If necessary, you also can create a TemporaryPintsCollection
that is accessed by SavedPointsCollection
.
To implement a custom collection you can either override System.Collections.ObjectModel.Collection<T>
or implement the IList<T>
interface. Collection<T>
is good when you want to use a standard collection for an item type. When you want to do more fancy features, suche as a fixed-size collection, you can use IList<T>
.
Here's an example with an (incomplete) IList<T>
implementation:
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;
}
}
}
Upvotes: 1
Reputation: 5920
If you want to do such thing you can override this[]
indexer property but you should create a property TemporaryPoints
instead of making it a public field
. These you can combine to create something like this:
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);
}
}
}
Since you cannot override "property's indexer property" you should make interface which allows you to set only the value on the specific index.
That's why there's this method : SetTemporaryPoint(int idx, PointF value)
.
After all you can use it almost the same as you wanted which is :
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]
But if you're really into using only this[]
indexer property. You can make some enumeration :
public enum POINTS_STORAGE { TEMPORARY = 0, SAVED = 1 };
Then in you this[]
indexer property :
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;
}
}
Then you can use it like :
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]
Upvotes: 0
Reputation: 4679
Not absolutely clear what you want but you could use an indexer:
protected PointF this[int index] // Indexer declaration
{
get
{
return _savedPoints[index];
}
set
{
_savedPoints[index] = value;
TemporaryPoints[index] = value;
}
}
You can then do:
var rect = new MyRectangle();
rect[0] = new PointF (1,1);
Upvotes: 0