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

C# LANGUAGE SPECIFICATION

1the A.f field is initialized with a delegate that refers to the second Square method because overload

2resolution with an argument list consisting of a lone double value would choose that method. Had the

3second Square method not been present, a compile-time error would have occurred.

4The definition of a method being consistent with a delegate type (§22.1) permits co-variance in the return

5type and contra-variance in the parameter types. That is, the method return type may be more specific than

6the delegate return type and the method parameter types may be less specific than the delegate parameter

7types. In the example

8delegate object StrToObj(string s);

9class A

10{

11

StrToObj f = new StrToObj(ObjToStr);

12

static string ObjToStr(object x) {

13

return x.ToString();

14}

15}

16the method ObjToStr is used to create a delegate of type StrToObj. The method is consistent with the

17delegate type since there is an implicit reference conversion from the parameter type of the delegate to the

18parameter type of the method and an implicit reference conversion from the return type of the method to the

19return type of the delegate. end example]

2014.5.11 The typeof operator

21The typeof operator is used to obtain the System.Type object for a type.

22typeof-expression:

23

typeof

(

type )

24

typeof

(

unbound-type-name )

25typeof ( void )

26unbound-type-name:

27

identifier generic-dimension-specifieropt

28

identifier :: identifier generic-dimension-specifieropt

29

unbound-type-name . identifier generic-dimension-specifieropt

30

generic-dimension-specifier:

31

< commasopt >

32

commas:

33

,

34

commas ,

35The first form of typeof-expression consists of a typeof keyword followed by a parenthesized type. The

36result of an expression of this form is the System.Type object for the indicated type. There is only one

37System.Type object for any given type. [Note: This means that for type T, typeof(T) == typeof(T)

38is always true. end note]

39The second form of typeof-expression consists of a typeof keyword followed by a parenthesized unbound-

40type-name. [Note: An unbound-type-name is very similar to a type-name (§10.8) except that an unbound-

41type-name contains generic-dimension-specifiers where a type-name contains type-argument-lists. end note]

42When the operand of a typeof-expression is a sequence of tokens that satisfies the grammars of both

43unbound-type-name and type-name, namely when it contains neither a generic-dimension-specifier nor a

44type-argument-list, the sequence of tokens is considered to be a type-name. The meaning of an unbound-

45type-name is determined as follows:

46Convert the sequence of tokens to a type-name by replacing each generic-dimension-specifier with a

47type-argument-list having the same number of commas and the keyword object as each type-

48argument.

176

Chapter 14 Expressions

1Evaluate the resulting type-name, while ignoring all type parameter constraints.

2The unbound-type-name resolves to the unbound generic type associated with the resulting constructed

3type (§26.5).

4The result of the typeof-expression is the System.Type object for the resulting unbound generic type.

5The third form of typeof-expression consists of a typeof keyword followed by a parenthesized void

6keyword. The result of an expression of this form is the System.Type object that represents the absence of

7a type. The type object returned by typeof(void) is distinct from the type object returned for any type.

8[Note: This special type object is useful in class libraries that allow reflection onto methods in the language,

9where those methods wish to have a way to represent the return type of any method, including void methods,

10with an instance of System.Type. end note]

11[Example: The example

12using System;

13class Test

14{

15

static void Main() {

 

16

Type[] t = {

 

17

typeof(int),

 

18

typeof(System.Int32),

19

typeof(string),

 

20

typeof(double[]),

 

21

typeof(void)

};

22

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

23

Console.WriteLine(t[i].FullName);

24

}

 

25}

26}

27produces the following output:

28System.Int32

29System.Int32

30System.String

31System.Double[]

32System.Void

33Note that int and System.Int32 are the same type. end example]

34The typeof operator can be used on a type-parameter (§26.1.1). The result is the System.Type object for

35the run-time type that was bound to the type-parameter. The typeof operator can also be used on a

36constructed type (§26.5) or an unbound generic type. The System.Type object for an unbound generic type

37is not the same as the System.Type object of the instance type. The instance type is always a closed

38constructed type at run-time so its System.Type object depends on the actual type arguments in use, while

39the unbound generic type has no type arguments. [Example:

40class X<T>

41{

42

public static void PrintTypes() {

43

Console.WriteLine(typeof(T).FullName);

44

Console.WriteLine(typeof(X<T>).FullName);

45

Console.WriteLine(typeof(X<X<T>>).FullName);

46

Console.WriteLine(typeof(X<>).FullName);

47}

48}

49class M

50{

51

static void Main() {

52

X<int>.PrintTypes();

53

X<string>.PrintTypes();

54}

55}

56The above program will print:

177

C# LANGUAGE SPECIFICATION

1System.Int32

2x`1[System.Int32]

3X`1[X`1[System.Int32]]

4X`1[T]

5System.String

6x`1[System.String]

7X`1[X`1[System.String]]

8X`1[T]

9Note that the result of typeof(X<>) does not depend on the type argument but the result of

10typeof(X<T>) does depend on the type argument. end example]

1114.5.12 The checked and unchecked operators

12The checked and unchecked operators are used to control the overflow checking context for integral-type

13arithmetic operations and conversions.

14checked-expression:

15checked ( expression )

16unchecked-expression:

17unchecked ( expression )

18The checked operator evaluates the contained expression in a checked context, and the unchecked

19operator evaluates the contained expression in an unchecked context. A checked-expression or unchecked-

20expression corresponds exactly to a parenthesized-expression (§14.5.3), except that the contained expression

21is evaluated in the given overflow checking context.

22The overflow checking context can also be controlled through the checked and unchecked statements

23(§15.11).

24The following operations are affected by the overflow checking context established by the checked and

25unchecked operators and statements:

26The predefined ++ and -- unary operators (§14.5.9 and §14.6.5), when the operand type is an integral

27or enum type.

28The predefined - unary operator (§14.6.2), when the operand type is an integral type.

29The predefined +, -, *, and / binary operators (§14.7), when the operand types are integral or enum

30types.

31Explicit numeric conversions (§13.2.1) from one integral or enum type to another integral or enum type,

32or from float or double to an integral or enum type.

33When one of the above operations produces a result that is too large to represent in the destination type, the

34context in which the operation is performed controls the resulting behavior:

35In a checked context, if the operation is a constant expression (§14.15), a compile-time error occurs.

36Otherwise, when the operation is performed at run-time, a System.OverflowException is thrown.

37In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the

38destination type.

39For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any

40checked or unchecked operators or statements, the default overflow checking context is unchecked,

41unless external factors (such as compiler switches and execution environment configuration) call for

42checked evaluation.

43For constant expressions (expressions that can be fully evaluated at compile-time), the default overflow

44checking context is always checked. Unless a constant expression is explicitly placed in an unchecked

45context, overflows that occur during the compile-time evaluation of the expression always cause compile-

46time errors.

178

Chapter 14 Expressions

1[Note: Developers might benefit if they exercise their code using checked mode (as well as unchecked

2mode). It also seems reasonable that, unless otherwise requested, the default overflow checking context is

3set to checked when debugging is enabled. end note]

4[Example: In the following code

5class Test

6{

7

static readonly int x = 1000000;

8

static readonly int y = 1000000;

9

static int F() {

 

10

return checked(x * y);

// Throws OverflowException

11

}

 

12

static int G() {

 

13

return unchecked(x * y);

// Returns -727379968

14

}

 

15

static int H() {

 

16

return x * y;

// Depends on default

17}

18}

19no compile-time errors are reported since neither of the expressions can be evaluated at compile-time. At

20run-time, the F method throws a System.OverflowException, and the G method returns –727379968

21(the lower 32 bits of the out-of-range result). The behavior of the H method depends on the default overflow

22checking context for the compilation, but it is either the same as F or the same as G. end example]

23[Example: In the following code

24class Test

25{

26

const int x = 1000000;

 

27

const int y = 1000000;

 

28

static int F() {

 

29

return checked(x * y);

// Compile error, overflow

30

}

 

31

static int G() {

 

32

return unchecked(x * y);

// Returns -727379968

33

}

 

34

static int H() {

 

35

return x * y;

// Compile error, overflow

36}

37}

38the overflows that occur when evaluating the constant expressions in F and H cause compile-time errors to

39be reported because the expressions are evaluated in a checked context. An overflow also occurs when

40evaluating the constant expression in G, but since the evaluation takes place in an unchecked context, the

41overflow is not reported. end example]

42The checked and unchecked operators only affect the overflow checking context for those operations that

43are textually contained within the “(” and “)” tokens. The operators have no effect on function members

44that are invoked as a result of evaluating the contained expression. [Example: In the following code

45class Test

46{

47

static int Multiply(int x, int y) {

48

return x * y;

49

}

50

static int F() {

51

return checked(Multiply(1000000, 1000000));

52}

53}

54

the use of checked in F does not affect the evaluation of x * y in Multiply, so x * y is evaluated in

55

the default overflow checking context. end example]

179

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