使用字符串作为IEnumerable

Seb*_*zus 20 .net c# string windows-8 windows-store-apps

在.NET for Windows Store Apps中 - 似乎 - 你不能再使用字符串作为Enumerables了.以下代码适用于桌面应用程序,但不适用于应用程序:

public static bool SolelyConsistsOfLetters(string s)
{
    return s.All(c => char.IsLetter(c));
}
Run Code Online (Sandbox Code Playgroud)

错误是

'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));
}
Run Code Online (Sandbox Code Playgroud)

问题是,s as IEnumerable<char>不起作用(错误:"无法将类型'字符串'转换为'System.Collections.Generic.IEnumerable'(...)")并且s.GetEnumerator()不可用.

我的问题:

  1. 是否真的没有优雅的方法来使用字符串作为Enumerables(没有上面的帮助方法)?我觉得我必须错过一些非常明显的东西.
  2. 由于字符串的行为不像Enumerable,foreach为什么/如何在这里工作?

Joã*_*elo 18

String.IEnumerable<Char>.GetEnumerator.NET for Windows Store应用程序不支持该方法,但是,String.IEnumerable.GetEnumerator支持非泛型,因此该foreach方法的工作原理.

基于此我相信它也应该可以做到:

s.Cast<char>().All(c => char.IsLetter(c))
Run Code Online (Sandbox Code Playgroud)

更新(关于Jani注释)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
Run Code Online (Sandbox Code Playgroud)

  • 我认为`Cast`在逻辑上比`OfType`更有意义.你不想过滤集合(这是'OfType`的作用). (3认同)
  • 并且"不支持"是指String不实现IEnumerable <char>.遗憾的是,MSDN API文档仅在成员上具有"支持"标志,而不是将WinRT作为平台进行浏览的能力,因为标题信息是错误的. (2认同)