20

在 .NET for Windows Store Apps 中——看起来——你不能再将字符串用作 Enumerables。以下代码适用于桌面应用程序,但不适用于应用程序:

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

错误是

“string”不包含“All”的定义,并且找不到接受“string”类型的第一个参数的扩展方法“All”(您是否缺少 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()不可用。

我的问题:

  1. 真的没有优雅的方式将字符串用作 Enumerables(没有上面的辅助方法)吗?我觉得我一定错过了一些非常明显的东西。
  2. 由于字符串的行为不像 Enumerable,为什么/如何在这里工作?
4

1 回答 1

19

String.IEnumerable<Char>.GetEnumeratorWindows Store 应用程序的 .NET 不支持该方法,但是String.IEnumerable.GetEnumerator支持非泛型,这就是该foreach方法有效的原因。

基于此,我认为也应该可以这样做:

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

更新(关于 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
于 2013-01-30T11:54:42.463 回答