Indexer Question
-
I have a class in which I have a property that returns an array of enums (which are declared in a class that is used by this class through a using statement). When I use this class, I access the property through the indexer. The enum and accessor look like: enum State { Flashing, Played, NotPlayed } class1.balls[i] = State.Played; Now, what I want to do is take action when the property is set through the indexer like in the example above. I want to know the value of the indexer (i) and what it is being set to. All the internet examples I see use a separate class for this, but that doesn't make sense to me. I can't see how to make the separate class access things within the original class I have the public property in. Thanks!
-
I have a class in which I have a property that returns an array of enums (which are declared in a class that is used by this class through a using statement). When I use this class, I access the property through the indexer. The enum and accessor look like: enum State { Flashing, Played, NotPlayed } class1.balls[i] = State.Played; Now, what I want to do is take action when the property is set through the indexer like in the example above. I want to know the value of the indexer (i) and what it is being set to. All the internet examples I see use a separate class for this, but that doesn't make sense to me. I can't see how to make the separate class access things within the original class I have the public property in. Thanks!
The C# spec has this to say about indexers: Indexer declarations are similar to property declarations, with the main differences being that indexers are nameless (the “name” used in the declaration is
this
, sincethis
is being indexed) and that indexers include indexing parameters. The indexing parameters are provided between square brackets. edit: page 60/553 of ECMA-334 4th edition (June 2006) Which means that you can not declare an indexer with a name, you can only use indexers to write expressions of the forminstance[parameter list]
To give it a name, you have to cheat - for example by having a field (with the wanted name, of course) of a type that has an indexer. Usually, that would be a field of an other type, which you created solely to be indexed. That type should, of course, have enough information to be indexed, but you could pass in the entire "parent" instance (edit: at the ctor, when you initialize that field). -
I have a class in which I have a property that returns an array of enums (which are declared in a class that is used by this class through a using statement). When I use this class, I access the property through the indexer. The enum and accessor look like: enum State { Flashing, Played, NotPlayed } class1.balls[i] = State.Played; Now, what I want to do is take action when the property is set through the indexer like in the example above. I want to know the value of the indexer (i) and what it is being set to. All the internet examples I see use a separate class for this, but that doesn't make sense to me. I can't see how to make the separate class access things within the original class I have the public property in. Thanks!
-
-
I have a class in which I have a property that returns an array of enums (which are declared in a class that is used by this class through a using statement). When I use this class, I access the property through the indexer. The enum and accessor look like: enum State { Flashing, Played, NotPlayed } class1.balls[i] = State.Played; Now, what I want to do is take action when the property is set through the indexer like in the example above. I want to know the value of the indexer (i) and what it is being set to. All the internet examples I see use a separate class for this, but that doesn't make sense to me. I can't see how to make the separate class access things within the original class I have the public property in. Thanks!
You do need a separate class to do what you want to do, and it needs to expose an event that the class that uses it must handle in order to respond to changes in ball states. Here's an example (compiles under VS2008):
namespace BallStateExample
{
enum State {Flashing, Played, NotPlayed}
delegate void BallStateChanged(BallStateChangedEventArgs e);class BallStateChangedEventArgs { public int BallIndex { get; set; } public State NewState { get; set; } } class Balls { private readonly State\[\] \_balls; public Balls(int numBalls) { \_balls = new State\[numBalls\]; } public event BallStateChanged BallStateChanged; private void OnBallStateChanged(int index, State newState) { if (BallStateChanged != null) BallStateChanged(new BallStateChangedEventArgs { BallIndex = index, NewState = newState }); } public State this\[int index\] { get { return \_balls\[index\]; } set { \_balls\[index\] = value; OnBallStateChanged(index, value); } } } class BallUser { private const int NUM\_BALLS = 42; public BallUser() { Balls = new Balls(NUM\_BALLS); Balls.BallStateChanged += Balls\_StateChanged; } private void Balls\_StateChanged(BallStateChangedEventArgs e) { // Take action in response to a ball state change } // ... // Auto-property (so no backing store need be declared) // Private set accessor to prevent consumers of BallUser from // assigning to the property (an action reserved for the constructor of BallUser). public Balls Balls { get; private set; } // ... } }