12

Random example:

ConfigurationElementCollection

.Net has tons of these little WhateverCollection classes that don't implement IEnumerable<T>, which means I can't use Linq to objects with them out of the box. Even before Linq, you'd think they would have wanted to make use of generics (which were introduced all the way back in C# 2 I believe)

It seems I run across these annoying little collection types all the time. Is there some technical reason?

Erix
  • 7,059
  • 2
  • 35
  • 61
  • 19
    They were introduced before generics were available. – Eric J. Jan 09 '13 at 15:21
  • 4
    You can technically use LINQ "out of the box" by using `OfType` or `Cast` if the collection tends to contain a strong type, so long as it at least implements `IEnumerable` (non-generic). `OfType`/`Cast` yield generic `IEnumerable` instances, and thus opens the rest of the LINQ operators. – Adam Houldsworth Jan 09 '13 at 15:23
  • And long have been since I last use ArrayList. – deerchao Jan 09 '13 at 15:23
  • 3
    @EricJ: Of course generics wasn't available in 1.0. But the real question is: "Why didn't the BCL team add a generic interface to those classes in .NET 2.0?". – Steven Jan 09 '13 at 15:23
  • Perhaps it would have been a breaking change, especially in respect to serialization/deserialization. – Matthew Watson Jan 09 '13 at 15:26
  • @Erix: http://stackoverflow.com/questions/812673/convert-cast-ienumerable-to-ienumerablet – shahkalpesh Jan 09 '13 at 15:26
  • @EricJ. Add that as an answer if you don't mind. – Erix Jan 09 '13 at 15:27

2 Answers2

7

The answer is in the question title: "named collections". Which is the way you had to make collections type-safe before generics became available. There are a lot of them in code that dates back to .NET 1.x, especially Winforms. There was no reasonable way to rewrite them using generics, that would have broken too much existing code.

So the named collection type is type safe but the rub is System.Collections.IEnumerator.Current, a property of type Object. You can Linqify these collections by using OfType() or Cast().

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

As Adam Houldsworth said in a comment already, you simply need to use the Cast<> method.

Example:

var a = new DogCollection();
var allFidos = a.Cast<Dog>().Where(d => d.Name == "Fido"); 
MgSam
  • 12,139
  • 19
  • 64
  • 95