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

Chapter 15 Statements

1o If there is not an implicit conversion from R to the System.IDisposable interface, then a

2compile-time error is produced.

3o Otherwise, if ResourceType is a value type or a type parameter with the value type constraint

4(§26.7), the finally clause is expanded to:

5finally {

6((System.IDisposable)resource).Dispose();

7}

8o Otherwise, the finally clause is expanded to:

9finally {

10if (resource != null) ((System.IDisposable)resource).Dispose();

11}

12When a resource-acquisition takes the form of a local-variable-declaration, it is possible to acquire multiple

13resources of a given type. A using statement of the form

14using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement

15is precisely equivalent to a sequence of nested using statements:

16using (ResourceType r1 = e1)

17

using (ResourceType r2 = e2)

18

...

19

using (ResourceType rN = eN)

20

statement

21[Example: The example below creates a file named log.txt and writes two lines of text to the file. The

22example then opens that same file for reading and copies the contained lines of text to the console.

23using System;

24using System.IO;

25class Test

26{

27

static void Main() {

28

using (TextWriter w = File.CreateText("log.txt")) {

29

w.WriteLine("This is line one");

30

w.WriteLine("This is line two");

31

}

32

using (TextReader r = File.OpenText("log.txt")) {

33

string s;

34

while ((s = r.ReadLine()) != null) {

35

Console.WriteLine(s);

36

}

37

}

38}

39}

40Since the TextWriter and TextReader classes implement the IDisposable interface, the example can

41use using statements to ensure that the underlying file is properly closed following the write or read

42operations. end example]

4315.14 The yield statement

44The yield statement is used in an iterator block (§27.1) to yield a value to the enumerator object or to

45signal the end of the iteration.

46yield-statement:

47

yield return expression ;

48yield break ;

49To ensure compatibility with existing programs, yield is not a keyword; yield has special meaning only

50when it is used immediately before a return or break keyword. In other contexts, yield can be used as

51an identifier.

239

C# LANGUAGE SPECIFICATION

1The are several restrictions on where a yield statement can appear, as described in the following.

2It is a compile-time error for a yield statement (of either form) to appear outside a method-body,

3operator-body, or accessor-body.

4It is a compile-time error for a yield statement (of either form) to appear inside an anonymous method.

5It is a compile-time error for a yield statement (of either form) to appear in the finally clause of a

6try statement.

7It is a compile-time error for a yield return statement to appear anywhere in a try statement that

8contains catch-clauses.

9[Example: The following example shows some valid and invalid uses of yield statements.

10delegate IEnumerable<int> D();

11IEnumerator<int> GetEnumerator() {

12

try {

 

13

yield return 1;

// Ok

14

yield break;

// Ok

15

}

 

16

finally {

 

17

yield return 2;

// Error, yield in finally

18

yield break;

// Error, yield in finally

19

}

 

20

try {

 

21

yield return 3;

// Error, yield return in try...catch

22

yield break;

// Ok

23

}

 

24

catch {

 

25

yield return 4;

// Error, yield return in try...catch

26

yield break;

// Ok

27

}

 

28

D d = delegate {

 

29

yield return 5;

// Error, yield in an anonymous method

30};

31}

32int MyMethod() {

33yield return 1; // Error, wrong return type for an iterator

34}

35end example]

36An implicit conversion (§13.1) shall exist from the type of the expression in the yield return statement to

37the yield type (§27.1.3) of the iterator block.

38A yield return statement is executed as follows:

39The expression given in the statement is evaluated, implicitly converted to the yield type, and assigned

40to the Current property of the enumerator object.

41Execution of the iterator block is suspended. If the yield return statement is within one or more try

42blocks, the associated finally blocks are not executed at this time.

43The MoveNext method of the enumerator object returns true to its caller, indicating that the

44enumerator object successfully advanced to the next item.

45The next call to the enumerator object’s MoveNext method resumes execution of the iterator block from

46where it was last suspended, namely at the end point of the yield return statement that caused the

47suspension.

48A yield break statement is executed as follows:

49If the yield break statement is enclosed by one or more try blocks with associated finally blocks,

50control is initially transferred to the finally block of the innermost try statement. When and if

240

Chapter 15 Statements

1control reaches the end point of a finally block, control is transferred to the finally block of the

2next enclosing try statement. This process is repeated until the finally blocks of all enclosing try

3statements have been executed.

4Control is returned to the caller of the iterator block. This is either the MoveNext method or Dispose

5method of the enumerator object.

6Because a yield break statement unconditionally transfers control elsewhere, the end point of a yield

7break statement is never reachable.

241

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