In .NET for Windows Store Apps –it seems– you cannot use strings as Enumerables anymore. The following code works for desktop applications, but not for apps:
public static bool SolelyConsistsOfLetters(string s)
{
return s.All(c => char.IsLetter(c));
}
The error is
'string' does not contain a definition for 'All' and no extension method 'All' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
But I'm not missing an assembly reference or using System.Linq;
. The following code does work:
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));
}
The problem is, s as IEnumerable<char>
does not work (error: "Cannot convert type 'string' to 'System.Collections.Generic.IEnumerable' (..)") and s.GetEnumerator()
is not available.
My questions:
In C#, all collections (eg lists, dictionaries, stacks, queues, etc) are enumerable because they implement the IEnumerable interface. So are strings. You can iterate over a string using a foreach block to get every character in the string.
IEnumerable has just one method called GetEnumerator. This method returns another type which is an interface that interface is IEnumerator. If we want to implement enumerator logic in any collection class, it needs to implement IEnumerable interface (either generic or non-generic).
IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.
IEnumerable interface is used when we want to iterate among our classes using a foreach loop. The IEnumerable interface has one method, GetEnumerator, that returns an IEnumerator interface that helps us to iterate among the class using the foreach loop.
The String.IEnumerable<Char>.GetEnumerator
method is not supported in .NET for Windows Store applications, however, the non generic String.IEnumerable.GetEnumerator
is supported so that's why the foreach
approach works.
Based on that I believe it should also be possible to do:
s.Cast<char>().All(c => char.IsLetter(c))
UPDATE (regarding Jani comment)
The foreach
is already performing the cast by defining the each variable as char
. The nongeneric IEnumerable
version returns object and at compile time every cast from object to any other type is acceptable so that's why it works.
The following code will also compile fine but will fail at runtime:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With