Я думаю, что это несоответствие между сообщением об ошибке и спецификацией.Как указывает kvb , спецификация допускает for ... in
только в двух случаях:
- Когда тип реализует универсальный интерфейс
IEnumerable<_>
(он же seq<_>
) - Когда тип имеет метод
GetEnumerator
, который возвращает тип с определенными свойствами
Если тип реализует неуниверсальный интерфейс IEnumerable
, тогда он не совпадаетлюбое из двух условий.Однако, если вы приведете его к IEnumerable
, тогда это будет тип IEnumerable
, который соответствует второму условию.Наличие GetEnumerator
члена непосредственно в типе (как предлагает desco) также является правильным, поскольку оно также соответствует второму случаю.
Итак, я думаю, что сообщение об ошибке неверно, потому что оно говорит, что реализация не-generic IEnumerable
достаточно, но на самом деле это не так.
Однако, похоже, существует одна фактическая ошибка компилятора, связанная с циклом for
.Вы получаете «внутреннюю ошибку» компилятора, когда пишете следующий код (что неверно, потому что предполагаемый универсальный тип возвращаемого значения не реализует IEnumerator
):
type Foo() =
member x.GetEnumerator () = null
for x in Foo() do () // Internal error here