最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Need help on the working of IEnumerable in C# - Stack Overflow

programmeradmin1浏览0评论

I want to know the basic IEnumerable functionality uses in LINQ.

See my code:

string[] fruits = new string[] {"apple", "plum", "cherry"};

IEnumerable<string> results = from a in fruits  
                              select a; 

My question is:

In the first line I am declaring a string array, string array is an IEnumerable type right?

In the second line, we are initializing a variable of type IEnumerable and applying LINQ query to fetch the results.

Even though string array (fruits) is an IEnumerable type, what is the need of casting it into an IEnumerable type again?

Could anyone help me to understand this simple question.

I want to know the basic IEnumerable functionality uses in LINQ.

See my code:

string[] fruits = new string[] {"apple", "plum", "cherry"};

IEnumerable<string> results = from a in fruits  
                              select a; 

My question is:

In the first line I am declaring a string array, string array is an IEnumerable type right?

In the second line, we are initializing a variable of type IEnumerable and applying LINQ query to fetch the results.

Even though string array (fruits) is an IEnumerable type, what is the need of casting it into an IEnumerable type again?

Could anyone help me to understand this simple question.

Share Improve this question edited Feb 1 at 6:29 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Feb 1 at 5:37 stackoverflowresearch456 sstackoverflowresearch456 s 591 silver badge5 bronze badges 8
  • Even though string array-(fruits) is an IEnumerable type what is the need of casting it into an IEnumerable type again? ?? – Ivan Petrov Commented Feb 1 at 5:40
  • Just "var" your LINQ queries' output. It's not always easy to assume what's being returned (once you start "ordering", etc.); "var" will tell you that (hover); and you can replace it later (hover and update). – Gerry Schmitz Commented Feb 1 at 5:50
  • 4 "what is the need of casting it into an IEnumerable type again" - there is no casting happening in your code. – Guru Stron Commented Feb 1 at 5:51
  • @ Ivan Petrov -I mean array actually implement IEnumerable Interface right.Then why should we explicitly cast again?Why we cant directly use foreach in fruits array to get the result? – stackoverflowresearch456 s Commented Feb 1 at 5:54
  • 4 @stackoverflowresearch456s and I will repeat myself - there is no explicit cast in your code, explicit cast would be IEnumerable<string> result = (IEnumerable<string>)fruits and it is indeed would be pointless. – Guru Stron Commented Feb 1 at 6:00
 |  Show 3 more comments

2 Answers 2

Reset to default 4

In the first line I am declaring a string array, String array is a IEnumerable type right?

Yes, it is not only just IEnumerable but IEnumerable<string> also.

In the second line, we are initializing a variable of type IEnumerable and applying LINQ query to fetch the results

Actually there is no fetching results here happening since enumeration is lazy and you have not applied an operation which will trigger it (like ToArray(), ToList(), Count(), foreach etc...)

The following:

IEnumerable<string> results = from a in fruits  
                      select a; 

Is actually turned by the compile in something like:

IEnumerable<string> results = fruits.Select(a => a); 

Which is call to the Enumerable.Select extension method. Note that results is an IEnumerable<string> but not an array, i.e. Console.WriteLine(results is string[]); will result in False while Console.WriteLine(fruits is string[]); is obviously True.

Also note that select can contain some data manipulations like select a + " is a fruit!", which will not change the data type of the returned value (in the provided case, but you can use one which will) but will result in different data returned on enumeration.

Decompilation to C# @sharplab.

what is the need of casting it into an IEnumerable type again?

There is no casting, you are explicitly defining variable type for new variable result. You could use var i.e. var result = ... (though compiler would determine the type to be the same - IEnumerable<string>)

I think your real question might be:

Why do LINQ's operators return an IEnumerable<string> and not for example string[] even though string[] implements IEnumerable<string>?

Microsoft could have implemented something similar to this for the Where operator (and other LINQ Operators) - work with C<T> concrete types instead of IEnumerable<T>:

public static class LinqExtensions {

    public static C Where<C, T>(this C collection, Func<T, bool> predicate)
    where C : ICollection<T>, new() {
        var filtered = new C();

        foreach (var element in collection) {
            if (predicate(element)) {
                filtered.Add(element);
            }
        }
        return filtered;
    }
}

so then you could write what you want:

string[] filtered = stringArray.Where(x => x.Contains("foo"));

As you see - we have to be able to initialize a new C and also be able to Add the filtered items. This means that we no longer can work with just IEnumerable<T>, we have to work with ICollection<T> which guarantees us the Add method.

But the real issue is that we HAVE to eagerly build the concrete type at each step.

Imagine we had a more real-life scenario where we stacked conditions:

string[] filteredArray = stringArray
.Where(x => x.Contains("hello")
.Where(x => x.Length>5);

With the concrete-type approach, we would build TWO arrays in the process at each step. But if we just returned IEnumerable<string> instead of string[] we can

  1. Delay the filtering operation until a later point
  2. Possibly apply both filters in one enumeration step
  3. Have option of what concrete type to materialize to - maybe we would need a List<string> instead of string[]
发布评论

评论列表(0)

  1. 暂无评论