Подтвердить что ты не робот

Использование строки как IEnumerable

В .NET для Windows Store Apps – кажется, – вы больше не можете использовать строки в качестве Enumerables. Следующий код работает для настольных приложений, но не для приложений:

public static bool SolelyConsistsOfLetters(string s)
{
    return s.All(c => char.IsLetter(c));
}

Ошибка

'string' не содержит определения для 'All' и не используется метод расширения 'All', принимающий первый аргумент типа 'string' (вам не хватает директивы using или ссылки на сборку?)

Но мне не хватает ссылки на сборку или using System.Linq;. Следующий код работает:

public static IEnumerable<char> StringAsEnumerable(string s)
{
    foreach (char c in s)
    {
        yield return c;
    }
}

public static bool SolelyConsistsOfLetters(string s)
{
    return StringAsEnumerable(s).All(c => char.IsLetter(c));
}

Проблема заключается в том, что s as IEnumerable<char> не работает (ошибка: "Невозможно преобразовать тип" строка "в" System.Collections.Generic.IEnumerable "(..)" ) и s.GetEnumerator() недоступно.

Мои вопросы:

  • Неужели нет элегантного способа использования строк в качестве Enumerables (без вспомогательного метода, как указано выше)? Я чувствую, что я должен упустить что-то совершенно очевидное.
  • Так как строка не ведет себя как Enumerable, почему/как здесь работает foreach?
4b9b3361

Ответ 1

Метод String.IEnumerable<Char>.GetEnumerator не поддерживается в приложениях .NET для Windows Store, однако не общий String.IEnumerable.GetEnumerator, поэтому подход foreach работает.

Исходя из этого, я считаю, что также можно сделать:

s.Cast<char>().All(c => char.IsLetter(c))

ОБНОВЛЕНИЕ (относительно комментария Яни) foreach уже выполняет бросок, определяя каждую переменную как char. Негенерическая версия IEnumerable возвращает объект, и во время компиляции любое преобразование из объекта в любой другой тип приемлемо, поэтому он работает.

Следующий код также будет компилироваться отлично, но будет работать во время выполнения:

var valid = new object[] {'1', '2', '3'};

foreach (char c in valid)
    Console.WriteLine(c);

var invalid = new object[] { 1, 2, 3 };

foreach (char c in invalid)
    Console.WriteLine(c); // Fails at runtime; InvalidCastException