Why is this not working?

This code works:

foreach(DataColumn column in table.Columns) { // do whatever } 

But this code does not:

 (IEnumerable<DataColumn>)(table.Columns) 

The .Columns property returns a DataColumnCollection , which is an InternalDataCollectionBase that implements IEnumerable, so it should work.

The error I get is

Cannot convert type 'System.Data.DataColumnCollection' to 'System.Collections.Generic.IEnumerable'

+7
source share
5 answers

DataColumnCollection implements IEnumerable , and each row returned is a DataColumn , but does not implement IEnumerable<DataColumn> . Since it does not implement an interface, you cannot pass it to an interface. Since the class is sealed, the compiler knows that this value cannot implement the interface, so you cannot even give it at compile time.

Use the LINQ Cast insted method:

 table.Columns.Cast<DataColumn>() 

This is an efficient adapter method — every element in a column collection will be lazily discarded by the DataColumn when you extract it from the result.

The reason for compiling foreach is because the compiler adds an explicit cast for you. For example, this will compile:

 foreach (string x in table.Columns) { } 

... but it will throw an exception at runtime.

+19
source

This is because the DataColumnCollection implements IEnumerable , but not IEnumerable<T> .

var columns = (IEnumerable)(table.Columns) should work

IEnumerable and IEnumerable are not related in any way. (however, IEnumerable<DataColumn> inherits from IEnumerable<object> , which can be duck typed into IEnumerable using dynamic, but it really won't help you (even if it's a lot of fun))

+3
source

In the first case, you individually go around each time in the Columns collection, but in the second you drop the entire collection at once. This is no different from:

 // Cats implements IAnimal Cats[] cats = new Cats[20]; ... IAnimal animal = cats[0]; 

against

 // this you cannot do Cats[] cats = new Cats[20]; IAnimal[] animal = cats; 

However, this is a moot point, how can you do this:

 table.Columns.Cast<DataColumn>() 

And do it. Note that using Cast<> preferable to just getting a generic IEnumerable while maintaining strong typing.

+1
source

This is because the DataColumnCollection implements only IEnumerable , so you cannot relate it to the general version of IEnumerable<DataColumn> . When using foreach , the compiler casts for you for each element by convention.

0
source

Try the following:

 var columns = table.Columns as IEnumerable; 
0
source

All Articles