Najlepszym miejscem do zbadania tego jest C# language specification. Na przykład, w przypadku enumerables tu kilka fragmentów od specyfikacji:
10.14.2 przeliczalnego interfejsy
enumerable interfejsy są interfejsami nierodzajową System.Collections. IEnumerable i wszystkie instancje generycznego interfejsu System.Collections.Generic.Nieliczalne. Ze względu na zwięzłość, w tym rozdziale interfejsy te są oznaczone odpowiednio jako IEnumerable i IEnumerable.
...
10.14.5.1 GetEnumerator Metoda
przeliczalny obiekt zapewnia implementację z GetEnumerator metod IEnumerable i IEnumerable interfejsów. Obie metody uzyskujące GetEnumerator mają wspólną implementację , która nabywa i zwraca obiekt enumeratora . Obiekt modułu wyliczającego jest zainicjowany wartościami argumentów i wartością instancji zapisaną, gdy zainicjowano obiekt przeliczalny , w przeciwnym razie obiekt modułu wyliczającego działa jak opisano w §10.14.4.
ta wiąże się ładnie jak te interfejsy są faktycznie zdefiniowane w .NET BCL, choć byłoby to całkowicie możliwe, że różne (tj non-.NET) ramy, aby zapewnić podobną, zgodną implementację kompilator C# mógłby wtedy celować.
Fragmenty specyfikacji trudne do oddzielenia od.Framework NET jest zwykle oznaczony:
Uwaga: Ta sekcja ma zastosowanie tylko do implementacji C# w Microsoft .NET.
Na innej notatki, foreach
faktycznie nie wymagająIEnumerable
; może używać pewnego rodzaju "kaczego pisania", o którym można przeczytać w sekcji 8.8.4 specyfikacji.
Ach, więc tak naprawdę chodzi o * implementację * języka, a następnie? – Smashery
@Smashery: Myślę, że lepiej o tym myśleć, jeśli chodzi o implementację zgodnego * kompilatora *. – Ani
Na marginesie składnia LINQ * nie stawia również żadnych szczególnych wymagań; jak "foreach", jest całkowicie oparty na wzorcach. Drzewa wyrażeń są bardziej zależne, ale szczegóły tego tłumaczenia nie są tak naprawdę w specyfikacji. –