Tài liệu What Is an Indexer? - Pdf 87



What Is an Indexer?
An indexer is a smart array in exactly the same way that a property is a smart field. The
syntax that you use for an indexer is exactly the same as the syntax you use for an array.
Let's work through an example. First, we'll examine a problem and see a weak solution
that doesn't use indexers. Then we'll work through the same problem and look at a better
solution that does use indexers. The problem concerns integers, or more precisely, the int
type.
An Example That Doesn't Use Indexers
You normally use an int to hold an integer value. Internally an int stores its value as a
sequence of 32 bits, where each bit can be either 0 or 1. Most of the time you don't care
about this internal binary representation; you just use an int type as a bucket to hold an
integer value. However, sometimes programmers use the int type for other purposes;
some programs manipulate the individual bits within an int. (If you are an old C
programmer you should feel at home with what follows!) In other words, occasionally a
program might use an int because it holds 32 bits and not because it can represent an
integer.
NOTE
Some older programs might use int types to try to save memory. A single int holds 32
bits, each of which can be 1 or 0. In some cases, programmers assigned 1 to indicate a
value of true and 0 to indicate false, and then employed an int as a set of Boolean values.
For example, the following expression uses the << and & bit manipulation operators to
find out whether the bit at index 6 of the int called bits is set to 0 or to 1:
(bits & (1 << 6)) != 0
If the bit at index 6 is 0, this expression evaluates to false; if the bit at index 6 is 1, this
expression evaluates to true. This is a fairly complicated expression, but it's trivial in
comparison to the following expression that sets the bit at index 6 to 0:
bits &= ~(1 << 6)
It's also trivial compared with this expression that sets the bit at index 6 to 1:
bits |= (1 << 6)

32 bits! In other words, if bits is an int, what we'd like to be able to write to access the bit
at index 6 is:
bits[6]
And, for example, set the bit at index 6 to true, we'd like to be able to write:
bits[6] = true
Unfortunately, you can't use the square bracket notation on an int. It only works on an
array or on a type that behaves like an array; that is, on a type that declares an indexer. So
the solution to the problem is to create a new type that acts like, feels like, and is used
like an array of bool variables but is implemented by using an int. Let's call this new type
IntBits. IntBits will contain an int value (initialized in its constructor), but the idea is that
we'll use IntBits as an array of bool variables.
TIP
Because IntBits is small and lightweight, it makes sense to create it as a struct rather than
as a class.
struct IntBits
{
public IntBits(int initialBitValue)
{
bits = initialBitValue;
}

// indexer to be written here

private int bits;
}
To define the indexer, you use a notation that is a cross between a property an an array.
The indexer for the IntBits struct looks like this:
struct IntBits
{
...

The argument specified in the indexer declaration is populated with the index
value specified when the indexer is called. The get and set accessor methods can
read this argument to determine which element should be accessed.
NOTE
You should perform a range check on the index value in the indexer to prevent any
unexpected exceptions from occurring in your indexer code.
After the indexer has been declared, we can use a variable of type IntBits instead of an int
and apply the square bracket notation as desired:
int adapted = 63;
IntBits bits = new IntBits(adapted);
bool peek = bits[6]; // retrieve bool at index 6
bits[0] = true; // set the bit at index 0 to true
bits[31] = false; // set the bit at index 31 to false
This syntax is certainly much easier to understand. It directly and succinctly captures the
essence of the problem.
NOTE
Indexers and properties are similar in that both use get and set accessors. An indexer is
like a property with multiple values. However, although you're allowed to declare static
properties, static indexers are illegal.
Understanding Indexer Accessors
When you read an indexer, the compiler automatically translates your array-like code into
a call to the get accessor of that indexer. For example, consider the following example:
bool peek = bits[6];
This statement is converted into a call to the get accessor for bits, and the value of the
index argument is set to 6.
Similarly, if you write to an indexer, the compiler automatically translates your array-like
code into a call to the set accessor of that indexer, setting the index argument to the
specified value. For example, consider the following statement:
bits[6] = true;
This statement is converted into a call to the set accessor for bits where the value of index


Nhờ tải bản gốc
Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status