Megosztás a következőn keresztül:


A GetEnumerator hurkok támogatása a foreach kiegészítéssel.

Jegyzet

Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.

A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.

A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.

Bajnok kérdés: https://github.com/dotnet/csharplang/issues/3194

Összefoglalás

Lehetővé teszi, hogy a foreach hurkok felismerjék a GetEnumerator bővítménymetódust, amely egyébként megfelel a foreach-mintának, és a kifejezésen hurkoljanak, amikor az egyébként hibát okozna.

Motiváció

Ez azt eredményezi, hogy a foreach összhangba kerül a C# többi funkciójának megvalósítási módjával, beleértve az aszinkron és a mintaalapú dekonstruálást is.

Részletes kialakítás

A specifikáció változása viszonylag egyszerű. A The foreach statement§13.9.5 szakaszt a következő szövegre módosítjuk:

A foreach utasítás fordítási idejének feldolgozása először meghatározza a gyűjteménytípust, enumerátortípust és elemtípust a kifejezés. Ez a meghatározás a következőképpen folytatódik:

  • Ha a X típusa tömbtípus, akkor implicit hivatkozási átalakítás történik X-ről IEnumerable interfészre (mivel System.Array implementálja ezt a felületet). A gyűjteménytípus a IEnumerable felület, a enumerátortípus a IEnumerator felület, az elemtípus pedig a tömbtípus Xelemtípusa.

  • Ha a X típusa dynamic, akkor van egy implicit átalakítás, amely a kifejezés-t a IEnumerable interfészre alakítja át (§10.2.10). A gyűjteménytípus a IEnumerable felület, a enumerátortípus pedig a IEnumerator felület. Ha a var azonosítót a local_variable_type adja meg, akkor a elemtípusdynamic, ellenkező esetben object.

  • Egyéb esetben állapítsa meg, hogy a X típus rendelkezik-e megfelelő GetEnumerator metódussal:

    • Tagkeresést hajt végre a típus X azonosító GetEnumerator és típusargumentumok nélkül. Ha a tagkeresés nem hoz létre egyezést, vagy kétértelműséget eredményez, vagy olyan egyezést hoz létre, amely nem metóduscsoport, keressen egy számbavételi felületet az alábbiak szerint. Javasoljuk, hogy figyelmeztetést adjon ki, ha a tagkeresés egy metóduscsoporton kívül bármit is létrehoz, vagy nincs egyezés.
    • Túlterhelés feloldása az eredményként kapott metóduscsoport és egy üres argumentumlista használatával. Ha a túlterhelés feloldása nem eredményez alkalmazható metódusokat, kétértelműséget eredményez, vagy egyetlen legjobb módszert eredményez, de ez a módszer statikus vagy nem nyilvános, ellenőrizze az alábbiakban ismertetett számbavételi felületet. Javasoljuk, hogy figyelmeztetést adjon ki, ha a túlterhelés feloldása nem hoz létre semmit, kivéve egy egyértelmű nyilvános példány metódusát, vagy nem alkalmazható metódusokat.
    • Ha a E metódus visszatérési típusa GetEnumerator nem osztály, struktúra vagy illesztőtípus, hibaüzenet jelenik meg, és nem történik további lépés.
    • E az azonosító Current alapján történik a tagkeresés, típusargumentumok nélkül. Ha a tagkeresés nem hoz létre egyezést, az eredmény hiba, vagy az eredmény nem más, mint egy olvasást lehetővé tevő nyilvános példánytulajdonság, hiba keletkezik, és nem történik további lépés.
    • E az azonosító MoveNext alapján történik a tagkeresés, típusargumentumok nélkül. Ha a tagkeresés nem hoz létre egyezést, az eredmény hiba, vagy az eredmény egy metóduscsoport kivételével bármi, hiba keletkezik, és nem történik további lépés.
    • A túlterhelés feloldása üres argumentumlistával történik a metóduscsoporton. Ha a túlterhelés feloldása nem eredményez megfelelő metódusokat, kétértelműséget eredményez, vagy egyetlen legjobb módszert eredményez, de ez a módszer statikus vagy nem nyilvános, vagy a visszatérési típusa nem bool, hiba keletkezik, és nem történik további lépés.
    • A gyűjteménytípusX, a enumerátortípusE, az .
  • Ellenkező esetben ellenőrizze, hogy van-e felsorolható felület:

    • Ha minden Ti típus közül, amelyre létezik egy implicit konverzió X-ről IEnumerable<Ti>-re, létezik egy egyedi T típus, olyan, hogy T nem dynamic, és minden más Ti esetében van egy implicit konverzió IEnumerable<T>-ről IEnumerable<Ti>-re, akkor a gyűjteménytípus az interfész IEnumerable<T>, az enumerátortípus az interfész IEnumerator<T>, és a elemtípus pedig T.
    • Ellenkező esetben, ha egynél több ilyen típusú Tvan, akkor a rendszer hibát okoz, és nem hajt végre további lépéseket.
    • Ellenkező esetben, ha implicit átalakítás történik X-ről System.Collections.IEnumerable interfészre, akkor a gyűjteménytípus ez az interfész, a enumerátortípus az interfész System.Collections.IEnumerator, az elemtípus pedigobject.
  • Egyéb esetben állapítsa meg, hogy az "X" típus rendelkezik-e megfelelő GetEnumerator kiterjesztési módszerrel:

    • Bővítménymetódus-keresés végrehajtása a X típuson GetEnumeratorazonosítóval. Ha a tagkeresés nem hoz létre egyezést, vagy kétértelműséget eredményez, vagy olyan egyezést hoz létre, amely nem metóduscsoport, a rendszer hibát okoz, és nem végez további lépéseket. Javasolt, hogy figyelmeztetést adjanak ki, ha a tagkeresés nem metóduscsoportot eredményez, vagy ha nincs egyezés.
    • Túlterhelésfeloldás végrehajtása az eredményként kapott metóduscsoport és a Xtípusú egyetlen argumentum használatával. Ha a túlterhelés feloldása során nem hoz létre alkalmazható metódusokat, kétértelműséget eredményez, vagy egyetlen legjobb metódust eredményez, de ez a metódus nem érhető el, hibaüzenet keletkezik és nem történik további lépés.
      • Ez az állásfoglalás lehetővé teszi, hogy a ref az első argumentumot adja át, ha X egy strukturáltípus, és a ref típusa in.
    • Ha a E metódus visszatérési típusa GetEnumerator nem osztály, struktúra vagy illesztőtípus, hibaüzenet jelenik meg, és nem történik további lépés.
    • E az azonosító Current alapján történik a tagkeresés, típusargumentumok nélkül. Ha a tagkeresés nem hoz létre egyezést, az eredmény hiba, vagy az eredmény nem más, mint egy olvasást lehetővé tevő nyilvános példánytulajdonság, hiba keletkezik, és nem történik további lépés.
    • E az azonosító MoveNext alapján történik a tagkeresés, típusargumentumok nélkül. Ha a tagkeresés nem hoz létre egyezést, az eredmény hiba, vagy az eredmény egy metóduscsoport kivételével bármi, hiba keletkezik, és nem történik további lépés.
    • A túlterhelés feloldása üres argumentumlistával történik a metóduscsoporton. Ha a túlterhelés feloldása nem eredményez megfelelő metódusokat, kétértelműséget eredményez, vagy egyetlen legjobb módszert eredményez, de ez a módszer statikus vagy nem nyilvános, vagy a visszatérési típusa nem bool, hiba keletkezik, és nem történik további lépés.
    • A gyűjteménytípusX, a enumerátortípusE, az .
  • Ellenkező esetben hibaüzenet jelenik meg, és nem történik további lépés.

A await foreachesetében a szabályok hasonlóképpen módosulnak. Az egyetlen változás, amely szükséges a specifikációhoz, az a Extension methods do not contribute. sor eltávolítása a leírásból, mivel a specifikáció többi része a fenti szabályokra épül, csak a minták módszerei helyett más neveket alkalmaznak.

Hátránya

Minden módosítás további összetettséggel bővíti a nyelvet, és ez lehetővé teszi, hogy azokat a dolgokat, amelyeket nem úgy terveztek, hogy foreachlegyen foreach, például Range.

Alternatívák

Nem csinál semmit.

Megoldatlan kérdések

Jelenleg egyik sem.