GetEnumeratorCompatibilidad con la extensión para los foreach bucles.Extension GetEnumerator support for foreach loops.
ResumenSummary
Permite que los bucles foreach reconozcan un método GetEnumerator del método de extensión que, de otro modo, satisface el patrón foreach y se recorre la expresión cuando, de lo contrario, es un error.Allow foreach loops to recognize an extension method GetEnumerator method that otherwise satisfies the foreach pattern, and loop over the expression when it would otherwise be an error.
MotivaciónMotivation
Esto hará que foreach esté alineado con cómo se implementan otras características de C#, incluida la desconstrucción asincrónica y basada en patrones.This will bring foreach inline with how other features in C# are implemented, including async and pattern-based deconstruction.
Diseño detalladoDetailed design
El cambio de especificación es relativamente sencillo.The spec change is relatively straightforward. Modificamos The foreach statement la sección de este texto:We modify The foreach statement section to this text:
El procesamiento en tiempo de compilación de una instrucción foreach primero determina el tipo de colección _, el tipo de _enumerador_ y el tipo de elemento de la expresión.The compile-time processing of a foreach statement first determines the collection type _, _enumerator type_ and _ element type of the expression. Esta determinación se realiza de la siguiente manera:This determination proceeds as follows:
Si el tipo
Xde expresión es un tipo de matriz, hay una conversión de referencia implícita deXa laIEnumerableinterfaz (puesto queSystem.Arrayimplementa esta interfaz).If the typeXof expression is an array type then there is an implicit reference conversion fromXto theIEnumerableinterface (sinceSystem.Arrayimplements this interface). * El tipo de colección _ es laIEnumerableinterfaz, el tipo de enumerador es laIEnumeratorinterfaz y el tipo de elemento _ * es el tipo de elemento del tipo de matrizX.The collection type _ is theIEnumerableinterface, the _enumerator type_ is theIEnumeratorinterface and the _ element type is the element type of the array typeX.Si el tipo
Xde expresión esdynamic, hay una conversión implícita de la expresión a laIEnumerableinterfaz (conversiones dinámicas implícitas).If the typeXof expression isdynamicthen there is an implicit conversion from expression to theIEnumerableinterface (Implicit dynamic conversions). * El tipo de colección _ es laIEnumerableinterfaz y el tipo de enumerador es laIEnumeratorinterfaz.The collection type _ is theIEnumerableinterface and the _enumerator type*_ is theIEnumeratorinterface. Si elvaridentificador se proporciona como _local_variable_type *, el tipo de elemento esdynamic, de lo contrario, esobject.If thevaridentifier is given as the _local_variable_type* then the element type isdynamic, otherwise it isobject.De lo contrario, determine si el tipo
Xtiene unGetEnumeratormétodo adecuado:Otherwise, determine whether the typeXhas an appropriateGetEnumeratormethod:
- Realiza la búsqueda de miembros en el tipo
Xcon el identificadorGetEnumeratory ningún argumento de tipo.Perform member lookup on the typeXwith identifierGetEnumeratorand no type arguments. Si la búsqueda de miembros no produce una coincidencia, o produce una ambigüedad, o produce una coincidencia que no es un grupo de métodos, busque una interfaz enumerable como se describe a continuación.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. Se recomienda emitir una advertencia si la búsqueda de miembros produce cualquier cosa, excepto un grupo de métodos o ninguna coincidencia.It is recommended that a warning be issued if member lookup produces anything except a method group or no match.- Realizar la resolución de sobrecarga utilizando el grupo de métodos resultante y una lista de argumentos vacía.Perform overload resolution using the resulting method group and an empty argument list. Si la resolución de sobrecarga da como resultado ningún método aplicable, da como resultado una ambigüedad o tiene como resultado un único método mejor pero ese método es estático o no público, busque una interfaz enumerable como se describe a continuación.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. Se recomienda emitir una advertencia si la resolución de sobrecarga produce todo excepto un método de instancia pública inequívoco o ningún método aplicable.It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
- Si el tipo de valor devuelto
EdelGetEnumeratormétodo no es una clase, una estructura o un tipo de interfaz, se genera un error y no se realiza ningún otro paso.If the return typeEof theGetEnumeratormethod is not a class, struct or interface type, an error is produced and no further steps are taken.- La búsqueda de miembros se realiza en
Econ el identificadorCurrenty sin argumentos de tipo.Member lookup is performed onEwith the identifierCurrentand no type arguments. Si la búsqueda de miembros no produce ninguna coincidencia, el resultado es un error o el resultado es cualquier cosa excepto una propiedad de instancia pública que permita la lectura, se genera un error y no se realiza ningún paso más.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.- La búsqueda de miembros se realiza en
Econ el identificadorMoveNexty sin argumentos de tipo.Member lookup is performed onEwith the identifierMoveNextand no type arguments. Si la búsqueda de miembros no produce ninguna coincidencia, el resultado es un error o el resultado es cualquier cosa excepto un grupo de métodos, se genera un error y no se realiza ningún paso más.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.- La resolución de sobrecarga se realiza en el grupo de métodos con una lista de argumentos vacía.Overload resolution is performed on the method group with an empty argument list. Si la resolución de sobrecarga da como resultado ningún método aplicable, da como resultado una ambigüedad o tiene como resultado un único método mejor pero ese método es estático o no público, o su tipo de valor devuelto no es
bool, se genera un error y no se realiza ningún otro paso.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 notbool, an error is produced and no further steps are taken.- El tipo de colección* es
X, el tipo de enumerador esEy el tipo de elemento _ * es el tipo de laCurrentpropiedad.The collection type _ isX, the _enumerator type_ isE, and the _ element type is the type of theCurrentproperty.De lo contrario, compruebe si hay una interfaz enumerable:Otherwise, check for an enumerable interface:
- Si entre todos los tipos
Tipara los que hay una conversión implícita deXaIEnumerable<Ti>, hay un tipo únicoT, de modo queTno esdynamicy para todos los demásTihay una conversión implícita deIEnumerable<T>aIEnumerable<Ti>, entonces el tipo de colección _ es la interfazIEnumerable<T>, el tipo de _enumerador*_ es la interfazIEnumerator<T>y el tipo de elemento _ * esT.If among all the typesTifor which there is an implicit conversion fromXtoIEnumerable<Ti>, there is a unique typeTsuch thatTis notdynamicand for all the otherTithere is an implicit conversion fromIEnumerable<T>toIEnumerable<Ti>, then the collection type _ is the interfaceIEnumerable<T>, the _enumerator type_ is the interfaceIEnumerator<T>, and the _ element type isT.- De lo contrario, si hay más de un tipo de este tipo
T, se genera un error y no se realiza ningún paso más.Otherwise, if there is more than one such typeT, then an error is produced and no further steps are taken.- De lo contrario, si hay una conversión implícita de
Xen laSystem.Collections.IEnumerableinterfaz, el tipo de colección* _ es esta interfaz, el tipo de enumerador es la interfazSystem.Collections.IEnumeratory el tipo de elemento _ * esobject.Otherwise, if there is an implicit conversion fromXto theSystem.Collections.IEnumerableinterface, then the collection type _ is this interface, the _enumerator type_ is the interfaceSystem.Collections.IEnumerator, and the _ element type isobject.De lo contrario, determine si el tipo ' X ' tiene un
GetEnumeratormétodo de extensión adecuado:Otherwise, determine whether the type 'X' has an appropriateGetEnumeratorextension method:
- Realice la búsqueda de métodos de extensión en el tipo
Xcon el identificadorGetEnumerator.Perform extension method lookup on the typeXwith identifierGetEnumerator. Si la búsqueda de miembros no produce una coincidencia, o produce una ambigüedad, o produce una coincidencia que no es un grupo de métodos, se genera un error y no se realiza ningún paso más.If the member lookup does not produce a match, or it produces an ambiguity, or produces a match which is not a method group, an error is produced and no further steps are taken. Se recomienda que se produzcan problemas si la búsqueda de miembros produce cualquier cosa, excepto un grupo de métodos o ninguna coincidencia.It is recommended that a warning be issues if member lookup produces anything except a method group or no match.- Realice la resolución de sobrecarga utilizando el grupo de métodos resultante y un único argumento de tipo
X.Perform overload resolution using the resulting method group and a single argument of typeX. Si la resolución de sobrecargas no produce ningún método aplicable, da como resultado una ambigüedad o tiene como resultado un único método mejor, pero no se puede tener acceso a ese método, se genera un error que indica que no se realiza ningún paso más.If overload resolution produces no applicable methods, results in an ambiguity, or results in a single best method but that method is not accessible, an error is produced an no further steps are taken.
- Esta resolución permite pasar el primer argumento por referencia si
Xes un tipo de estructura y el tipo de referencia esin.This resolution permits the first argument to be passed by ref ifXis a struct type, and the ref kind isin.- Si el tipo de valor devuelto
EdelGetEnumeratormétodo no es una clase, una estructura o un tipo de interfaz, se genera un error y no se realiza ningún otro paso.If the return typeEof theGetEnumeratormethod is not a class, struct or interface type, an error is produced and no further steps are taken.- La búsqueda de miembros se realiza en
Econ el identificadorCurrenty sin argumentos de tipo.Member lookup is performed onEwith the identifierCurrentand no type arguments. Si la búsqueda de miembros no produce ninguna coincidencia, el resultado es un error o el resultado es cualquier cosa excepto una propiedad de instancia pública que permita la lectura, se genera un error y no se realiza ningún paso más.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.- La búsqueda de miembros se realiza en
Econ el identificadorMoveNexty sin argumentos de tipo.Member lookup is performed onEwith the identifierMoveNextand no type arguments. Si la búsqueda de miembros no produce ninguna coincidencia, el resultado es un error o el resultado es cualquier cosa excepto un grupo de métodos, se genera un error y no se realiza ningún paso más.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.- La resolución de sobrecarga se realiza en el grupo de métodos con una lista de argumentos vacía.Overload resolution is performed on the method group with an empty argument list. Si la resolución de sobrecarga da como resultado ningún método aplicable, da como resultado una ambigüedad o tiene como resultado un único método mejor pero ese método es estático o no público, o su tipo de valor devuelto no es
bool, se genera un error y no se realiza ningún otro paso.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 notbool, an error is produced and no further steps are taken.- El tipo de colección* es
X, el tipo de enumerador esEy el tipo de elemento _ * es el tipo de laCurrentpropiedad.The collection type _ isX, the _enumerator type_ isE, and the _ element type is the type of theCurrentproperty.De lo contrario, se genera un error y no se realiza ningún paso más.Otherwise, an error is produced and no further steps are taken.
En await foreach el caso de, las reglas se modifican de forma similar.For await foreach, the rules are similarly modified. El único cambio necesario para esa especificación es quitar la Extension methods do not contribute. línea de la descripción, ya que el resto de esa especificación se basa en las reglas anteriores con nombres diferentes sustituidos por los métodos de patrón.The only change that is required to that spec is removing the Extension methods do not contribute. line from the description, as the rest of that spec is based on the above rules with different names substituted for the pattern methods.
InconvenientesDrawbacks
Cada cambio agrega complejidad adicional al lenguaje y esto permite potencialmente cosas que no se diseñaron para ser Ed foreach foreach , como Range .Every change adds additional complexity to the language, and this potentially allows things that weren't designed to be foreached to be foreached, like Range.
AlternativasAlternatives
No hacer nada.Doing nothing.
Preguntas no resueltasUnresolved questions
Ninguno en este momento.None at this point.