使用字符串作为IEnumerable

20

在 .NET Windows Store 应用中,似乎不能再将字符串作为可枚举对象使用。以下代码适用于桌面应用程序,但不适用于应用程序:

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>无法工作(错误:“无法将类型'string'转换为'System.Collections.Generic.IEnumerable'(..)”), 并且s.GetEnumerator()不可用。

我的问题:

  1. 真的没有更优雅的方法可以使用字符串作为可枚举对象(不使用上述帮助方法)吗? 我觉得我一定漏掉了什么非常明显的东西。
  2. 由于字符串不像可枚举对象那样运行,为什么/如何在此处使用foreach?

3
s as IEnumerable<char> 无法工作”的意思是什么?它实际上是做了什么? - svick
@svick:问题已更新 - Sebastian Negraszus
2
.NET for Windows Store 应用程序不支持 String.GetEnumerator(请参阅 String.GetHashCode 的相同页面)。我想编译器正在将 foreach 优化为 for 循环。 - Rawling
@Default:这也让我感到困惑。 - Sebastian Negraszus
1
@Rawling 是的,但那只是一种优化,如果没有 GetEnumerator() 它不应该被编译。此外,似乎支持非泛型的 GetEnumerator()(http://msdn.microsoft.com/en-us/library/bb344612.aspx)。@Sebastian s.Cast<char>().All(…) 可以工作吗? - svick
显示剩余3条评论
1个回答

20

String.IEnumerable<Char>.GetEnumerator方法在.NET for Windows Store应用程序中不受支持,但非泛型的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

3
我认为在这里使用“Cast”比“OfType”更有逻辑意义。您不希望过滤集合(这就是“OfType”所做的)。 - svick
如果非泛型能够正常工作,那么在foreach中是否需要进行类型转换呢? - Jahan Zinedine
2
而通过“不支持”你的意思是String没有实现IEnumerable<char>。遗憾的是,MSDN API文档只有对成员的“支持”标志,而没有浏览WinRT作为一个平台的能力,因为头部信息是错误的。 - Nicholas W
@Jani,我更新了答案。Nicholas,同意,那会少得多混淆。 - João Angelo
使用Cast并不如我希望的那么优雅,但目前似乎这是答案。已接受。 - Sebastian Negraszus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接