Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

The foreach statement

Anonymous function expressions | From, let, where, join and orderby clauses | Transparent identifiers | The query expression pattern | Simple assignment | Compound assignment | Constant expressions | End points and reachability | Local variable declarations | The switch statement |


Читайте также:
  1. A brief survey of control statements.
  2. A Decide which of these statements are true (T) or false (F).
  3. A. Decide whether each of the following statements is true or false. 1 страница
  4. A. Decide whether each of the following statements is true or false. 2 страница
  5. A. Decide whether each of the following statements is true or false. 3 страница
  6. A. Decide whether each of the following statements is true or false. 4 страница
  7. ACCOUNTING AND FINANCIAL STATEMENTS

The foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.

foreach-statement:
foreach (local-variable-type identifier in expression) embedded-statement

The type and identifier of a foreach statement declare the iteration variable of the statement. If the var identifier is given as the local-variable-type, and no type named var is in scope, the iteration variable is said to be an implicitly typed iteration variable, and its type is taken to be the element type of the foreach statement, as specified below. The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and ‑‑ operators) or pass the iteration variable as a ref or out parameter.

The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. This determination proceeds as follows:

· If the type X of expression is an array type then there is an implicit reference conversion from X to the System.Collections.IEnumerable interface (since System.Array implements this interface). The collection type is the System.Collections.IEnumerable interface, the enumerator type is the System.Collections.IEnumerator interface and the element type is the element type of the array type X.

· If the type X of expression is dynamic then there is an implicit conversion from expression to the System.Collections.IEnumerable interface (§6.1.8). The collection type is the System.Collections.IEnumerable interface and the enumerator type is the System.Collections.IEnumerator interface. If the var identifier is given as the local-variable-type then the element type is dynamic, otherwise it is object.

· Otherwise, determine whether the type X has an appropriate GetEnumerator method:

o Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.

o Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.

o If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.

o Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.

o Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.

o Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.

o The collection type is X, the enumerator type is E, and the element type is the type of the Current property.

· Otherwise, check for an enumerable interface:

o If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable<T>, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator<T>, and the element type is T.

o Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.

o Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.

o Otherwise, an error is produced and no further steps are taken.

The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form

foreach (V v in x) embedded-statement

is then expanded to:

{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}

The variable e is not visible to or accessible to the expression x or the embedded statement or any other source code of the program. The variable v is read-only in the embedded statement. If there is not an explicit conversion (§6.2) from T (the element type) to V (the local-variable-type in the foreach statement), an error is produced and no further steps are taken. If x has the value null, a System.NullReferenceException is thrown at run-time.

An implementation is permitted to implement a given foreach-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.

The body of the finally block is constructed according to the following steps:

· If there is an implicit conversion from E to the System.IDisposable interface, then

o If E is a non-nullable value type then the finally clause is expanded to the semantic equivalent of:

finally {
((System.IDisposable)e).Dispose();
}

o Otherwise the finally clause is expanded to the semantic equivalent of:

finally {
if (e!= null) ((System.IDisposable)e).Dispose();
}

except that if E is a value type, or a type parameter instantiated to a value type, then the cast of e to System.IDisposable will not cause boxing to occur.

· Otherwise, if E is a sealed type, the finally clause is expanded to an empty block:

finally {
}

· Otherwise, the finally clause is expanded to:

finally {
System.IDisposable d = e as System.IDisposable;
if (d!= null) d.Dispose();
}

The local variable d is not visible to or accessible to any user code. In particular, it does not conflict with any other variable whose scope includes the finally block.

The order in which foreach traverses the elements of an array, is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length – 1. For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left.

The following example prints out each value in a two-dimensional array, in element order:

using System;

class Test
{
static void Main() {
double[,] values = {
{1.2, 2.3, 3.4, 4.5},
{5.6, 6.7, 7.8, 8.9}
};

foreach (double elementValue in values)
Console.Write("{0} ", elementValue);

Console.WriteLine();
}
}

The output produced is as follows:

1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9

In the example

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);

the type of n is inferred to be int, the element type of numbers.


Дата добавления: 2015-11-16; просмотров: 59 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
The for statement| The goto statement

mybiblioteka.su - 2015-2024 год. (0.011 сек.)