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>機能せず (エラー:「タイプ 'string' を 'System.Collections.Generic.IEnumerable' に変換できません (..)」)、s.GetEnumerator()使用できないことです。

私の質問:

  1. 文字列を Enumerables として (上記のようなヘルパー メソッドなしで) 使用するエレガントな方法は本当にありませんか? 完全に明らかな何かを見逃しているに違いないと感じています。
  2. 文字列は Enumerable のように動作しないため、ここで foreach が機能する理由/方法は?
4

1 に答える 1

19

このString.IEnumerable<Char>.GetEnumeratorメソッドは Windows ストア アプリケーションの .NET ではサポートされていませんが、非ジェネリックString.IEnumerable.GetEnumeratorはサポートされているため、このforeachアプローチが機能します。

それに基づいて、次のこともできるはずだと思います:

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

UPDATE (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 に答える