Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a string as IEnumerable

Tags:

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:

  1. Is there really no elegant way to use strings as Enumerables (without a helper method as above)? I feel like I must be missing something totally obvious.
  2. Since the string does not behave like an Enumerable, why/how does foreach work here?
like image 943
Sebastian Negraszus Avatar asked Jan 30 '13 11:01

Sebastian Negraszus


People also ask

Does string implement IEnumerable?

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.

How do you declare an IEnumerable?

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).

What is IEnumerable <> in C#?

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.

Why do we use IEnumerable in C#?

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.


1 Answers

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
like image 181
João Angelo Avatar answered Oct 12 '22 05:10

João Angelo