Время от времени я вижу вопросы о крайних случаях и других странностях в переполнении стека, на которые легко отвечают такие люди, как Джон Скит и Эрик Липперт, демонстрирующие глубокое знание языка и многих его тонкостей, как этот:
Вы можете подумать, что для того, чтобы использовать
foreach
цикл, коллекция, которую вы перебираете, должна реализовыватьIEnumerable
илиIEnumerable<T>
. Но, как оказалось, это не является обязательным требованием. Требуется, чтобы у типа коллекции был открытый методGetEnumerator
, который должен возвращать некоторый тип, для которого вызываетсяCurrent
метод получения открытого свойства и открытый метод,MoveNext
который возвращает abool
. Если компилятор может определить, что все эти требования выполнены, генерируется код для использования этих методов. Только если эти требования не выполняются, мы проверяем, реализует ли объектIEnumerable
илиIEnumerable<T>
.
Это круто, что нужно знать. Я могу понять, почему Эрик знает это; он в команде компиляторов, поэтому он должен знать. Но как насчет тех, кто демонстрирует такие глубокие знания, которые не являются инсайдерами?
Как простые смертные (которые не входят в команду по компиляции C #) узнают о таких вещах?
В частности, существуют ли методы, которые эти люди используют, чтобы систематически выкорчевать такие знания, исследовать их и усваивать (делать их своими)?