Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C-sharp language specification.2004.pdf
Скачиваний:
14
Добавлен:
23.08.2013
Размер:
2.55 Mб
Скачать

Chapter 17 Classes

1Note that the syntax for accessing elements of the BitArray is precisely the same as for a bool[]. end

2example]

3[Example: The following example shows a 26×10 grid class that has an indexer with two parameters. The

4first parameter is required to be an upperor lowercase letter in the range A–Z, and the second is required to

5be an integer in the range 0–9.

6using System;

7class Grid

8{

9

const int NumRows = 26;

10

const int NumCols = 10;

11

int[,] cells = new int[NumRows, NumCols];

12

 

13

public int this[char c, int colm]

14

{

15

get {

16

c = Char.ToUpper(c);

17

if (c < 'A' || c > 'Z') {

18

throw new ArgumentException();

19

}

20

if (colm < 0 || colm >= NumCols) {

21

throw new IndexOutOfRangeException();

22

}

23

return cells[c - 'A', colm];

24

}

25

set {

26

c = Char.ToUpper(c);

27

if (c < 'A' || c > 'Z') {

28

throw new ArgumentException();

29

}

30

if (colm < 0 || colm >= NumCols) {

31

throw new IndexOutOfRangeException();

32

}

33

cells[c - 'A', colm] = value;

34

}

35}

36}

37end example]

3817.8.1 Indexer overloading

39The indexer overload resolution rules are described in §14.4.2.

4017.9 Operators

41An operator is a member that defines the meaning of an expression operator that can be applied to instances

42of the class. Operators are declared using operator-declarations:

43operator-declaration:

44

attributesopt operator-modifiers operator-declarator operator-body

45

operator-modifiers:

46

operator-modifier

47

operator-modifiers operator-modifier

48

operator-modifier:

49

public

50

static

51

extern

307

 

C# LANGUAGE SPECIFICATION

 

 

 

 

1

operator-declarator:

 

 

 

 

 

2

unary-operator-declarator

 

 

 

 

3

binary-operator-declarator

 

 

 

 

4

conversion-operator-declarator

 

 

 

5

unary-operator-declarator:

 

 

 

 

6

type operator overloadable-unary-operator ( type identifier )

7

overloadable-unary-operator: one of

 

 

8

+

-

!

~

++

--

 

true

false

9

binary-operator-declarator:

 

 

 

 

10

type operator overloadable-binary-operator ( type identifier , type identifier )

11

overloadable-binary-operator: one of

 

 

12

+

 

-

*

/

 

%

 

 

13

&

 

|

^

 

 

 

 

 

14

<<

 

right-shift

 

 

 

 

 

15

==

 

!=

>

<

 

>=

<=

 

16

conversion-operator-declarator:

 

 

 

 

17

implicit operator type ( type identifier )

18

explicit operator type ( type identifier )

19

operator-body:

 

 

 

 

 

 

20

block

 

 

 

 

 

 

 

 

21;

22There are three categories of overloadable operators: Unary operators (§17.9.1), binary operators (§17.9.2),

23and conversion operators (§17.9.3).

24When an operator declaration includes an extern modifier, the operator is said to be an external operator.

25Because an external operator provides no actual implementation, its operator-body consists of a semi-colon.

26For all other operators, the operator-body consists of a block, which specifies the statements to execute

27when the operator is invoked. The block of an operator shall conform to the rules for value-returning

28methods described in §17.5.8.

29The following rules apply to all operator declarations:

30An operator declaration shall include both a public and a static modifier.

31The parameter(s) of an operator shall be value parameters. It is a compile-time error for an operator

32declaration to specify ref or out parameters.

33The signature of an operator (§17.9.1, §17.9.2, §17.9.3) shall differ from the signatures of all other

34operators declared in the same class.

35All types referenced in an operator declaration shall be at least as accessible as the operator itself

36(§10.5.4).

37It is an error for the same modifier to appear multiple times in an operator declaration.

38Each operator category imposes additional restrictions, as described in the following subclauses.

39Like other members, operators declared in a base class are inherited by derived classes. Because operator

40declarations always require the class or struct in which the operator is declared to participate in the signature

41of the operator, it is not possible for an operator declared in a derived class to hide an operator declared in a

42base class. Thus, the new modifier is never required, and therefore never permitted, in an operator

43declaration.

44Additional information on unary and binary operators can be found in §14.2.

45Additional information on conversion operators can be found in §13.4.

308

Chapter 17 Classes

117.9.1 Unary operators

2The following rules apply to unary operator declarations, where T denotes the class or struct type that

3contains the operator declaration:

4A unary +, -, !, or ~ operator shall take a single parameter of type T and can return any type.

5A unary ++ or -- operator shall take a single parameter of type T and shall return type T or a type

6derived from T.

7A unary true or false operator shall take a single parameter of type T and shall return type bool.

8The signature of a unary operator consists of the operator token (+, -, !, ~, ++, --, true, or false) and the

9type of the single formal parameter. The return type is not part of a unary operator’s signature, nor is the

10name of the formal parameter.

11The true and false unary operators require pair-wise declaration. A compile-time error occurs if a class

12declares one of these operators without also declaring the other. The true and false operators are

13described further in §14.16.

14[Example: The following example shows an implementation and subsequent usage of operator++ for an

15integer vector class:

16public class IntVector

17{

18

public

int Length { … }

// read-only property

19

public

int this[int index] { … } // read-write indexer

20

public

IntVector(int vectorLength) { … }

21

public static IntVector operator++(IntVector iv) {

22

IntVector temp = new IntVector(iv.Length);

23

for (int i = 0; i < iv.Length; ++i)

24

temp[i] = iv[i] + 1;

 

25

return temp;

 

26}

27}

28class Test

29{

30

static void Main() {

31

IntVector iv1 = new IntVector(4); // vector of 4x0

32

IntVector iv2;

 

33

 

 

34

iv2 = iv1++;

// iv2 contains 4x0, iv1 contains 4x1

35

iv2 = ++iv1;

// iv2 contains 4x2, iv1 contains 4x2

36}

37}

38Note how the operator method returns the value produced by adding 1 to the operand, just like the postfix

39increment and decrement operators (§14.5.9), and the prefix increment and decrement operators (§14.6.5).

40Unlike in C++, this method need not, and, in fact, should not, modify the value of its operand directly. end

41example]

4217.9.2 Binary operators

43A binary operator shall take two parameters, at least one of which shall have the class or struct type in which

44the operator is declared. The shift operators (§14.8) are further constrained: The type of the first parameter

45shall be the class or struct type in which the operator is declared, and the second parameter shall always have

46the type int. A binary operator can return any type.

47The signature of a binary operator consists of the operator token (+, -, *, /, %, &, |, ^, <<, right-shift, ==,

48!=, >, <, >=, or <=) and the types of the two formal parameters. The return type and the names of the formal

49parameters are not part of a binary operator’s signature.

50Certain binary operators require pair-wise declaration. For every declaration of either operator of a pair,

51there shall be a matching declaration of the other operator of the pair. Two operator declarations match when

309

C# LANGUAGE SPECIFICATION

1they have the same return type and the same type for each parameter. The following operators require pair-

2wise declaration:

3operator == and operator !=

4operator > and operator <

5operator >= and operator <=

617.9.3 Conversion operators

7A conversion operator declaration introduces a user-defined conversion operator (§13.4), which augments

8the pre-defined implicit and explicit conversions.

9A conversion operator declaration that includes the implicit keyword introduces a user-defined implicit

10conversion operator. Implicit conversions can occur in a variety of situations, including function member

11invocations, cast expressions, and assignments. This is described further in §13.1.

12A conversion operator declaration that includes the explicit keyword introduces a user-defined explicit

13conversion operator. Explicit conversions can occur in cast expressions, and are described further in §13.2.

14A conversion operator converts from a source type, indicated by the parameter type of the conversion

15operator, to a target type, indicated by the return type of the conversion operator. A class or struct is

16permitted to declare a conversion operator from a source type S to a target type T provided all of the

17following are true:

18S and T are different types.

19Either S or T is the class or struct type in which the operator declaration takes place.

20Neither S nor T is object or an interface-type.

21T is not a base class of S, and S is not a base class of T.

22From the second rule it follows that a conversion operator shall convert either to or from the class or struct

23type in which the operator is declared. [Example: It is possible for a class or struct type C to define a

24conversion from C to int and from int to C, but not from int to bool. end example]

25It is not possible to redefine a pre-defined conversion. Thus, conversion operators are not allowed to convert

26from or to object because implicit and explicit conversions already exist between object and all other

27types. Likewise, neither the source nor the target types of a conversion can be a base type of the other, since

28a conversion would then already exist.

29User-defined conversions are not allowed to convert from or to interface-types. In particular, this restriction

30ensures that no user-defined transformations occur when converting to an interface-type, and that a

31conversion to an interface-type succeeds only if the object being converted actually implements the specified

32interface-type.

33The signature of a conversion operator consists of the source type and the target type. (This is the only form

34of member for which the return type participates in the signature.) The implicit or explicit

35classification of a conversion operator is not part of the operator’s signature. Thus, a class or struct cannot

36declare both an implicit and an explicit conversion operator with the same source and target types.

37[Note: In general, user-defined implicit conversions should be designed to never throw exceptions and never

38lose information. If a user-defined conversion can give rise to exceptions (for example, because the source

39argument is out of range) or loss of information (such as discarding high-order bits), then that conversion

40should be defined as an explicit conversion. end note]

41[Example: In the following code

42using System;

43public struct Digit

44{

45

byte value;

310

Соседние файлы в предмете Электротехника