Asked  7 Months ago    Answers:  5   Viewed   41 times

A new feature in C# / .NET 4.0 is that you can change your enumerable in a foreach without getting the exception. See Paul Jackson's blog entry An Interesting Side-Effect of Concurrency: Removing Items from a Collection While Enumerating for information on this change.

What is the best way to do the following?

foreach(var item in Enumerable)
{
    foreach(var item2 in item.Enumerable)
    {
        item.Add(new item2)
    }
}

Usually I use an IList as a cache/buffer until the end of the foreach, but is there better way?

 Answers

74

The collection used in foreach is immutable. This is very much by design.

As it says on MSDN:

The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.

The post in the link provided by Poko indicates that this is allowed in the new concurrent collections.

Tuesday, June 1, 2021
 
Eddas
answered 7 Months ago
81

Count() is an extension method introduced by LINQ while the Count property is part of the List itself (derived from ICollection). Internally though, LINQ checks if your IEnumerable implements ICollection and if it does it uses the Count property. So at the end of the day, there's no difference which one you use for a List.

To prove my point further, here's the code from Reflector for Enumerable.Count()

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<TSource> is2 = source as ICollection<TSource>;
    if (is2 != null)
    {
        return is2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}
Tuesday, June 29, 2021
 
alez
answered 6 Months ago
59

First of all, that should probably be out, not ref.

Second, you can declare and return a type containing the two lists.

Third, you can declare a generic Tuple and return an instance of that:

class Tuple<T,U> {
   public Tuple(T first, U second) { 
       First = first;
       Second = second;
   }
   public T First { get; private set; }
   public U Second { get; private set; }
}

static class Tuple {
   // The following method is declared to take advantage of
   // compiler type inference features and let us not specify
   // the type parameters manually.
   public static Tuple<T,U> Create<T,U>(T first, U second) {
        return new Tuple<T,U>(first, second);
   }
}

return Tuple.Create(firstList, secondList);

You can extend this idea for different number of items.

Wednesday, August 11, 2021
 
cbcp
answered 4 Months ago
42

Is it specified in the documentation for the class? No, then it's unspecified.

In terms of current implementations, there's no maximum size in RAM in the classes themselves, if you create a value type that's 2MB in size, push a few thousand into a list, and receive an out of memory exception, that's nothing to do with List<T>.

Internally, List<T>s workings would prevent it from ever having more than 2billion items. It's harder to come to a quick answer with Dictionary<TKey, TValue>, since the way things are positioned within it is more complicated, but really, if I was looking at dealing with a billion items (if a 32-bit value, for example, then 4GB), I'd be looking to store them in a database and retrieve them using data-access code.

At the very least, once you're dealing with a single data structure that's 4GB in size, rolling your own custom collection class no longer counts as reinventing the wheel.

Wednesday, August 18, 2021
 
jonboy
answered 4 Months ago
48

Your "hacky" solution looks fine to me.

Wednesday, October 13, 2021
 
Bruce
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share