2

What's the advantage of using this:

DataTable CopyToDataTable<T>(this IEnumerable<T> source) where T : DataRow

where you can just do this:

DataTable CopyToDataTable<T>(this DataRow[] source)

Excuse me if this is a dumb question, I'm new at this

Cleptus
  • 3,446
  • 4
  • 28
  • 34
Abdul Mahamaliyev
  • 750
  • 1
  • 8
  • 20
  • 1
    That code would make sense when using typed datatables/datarows. Check [Typed vs. untyped datasets](https://learn.microsoft.com/en-us/visualstudio/data-tools/typed-vs-untyped-datasets?view=vs-2019). Do note that the equivalent would be `this IEnumarable source` – Cleptus Aug 02 '21 at 08:29
  • But that would also inherit from DataRow right? @Cleptus – XWIKO Aug 02 '21 at 08:31
  • Yeah, both would work similar, the difference would be if you want to add the functionality to the type (the extension method) or not. Pretty much depends on your scenario and your liking. – Cleptus Aug 02 '21 at 08:32
  • Accepting `IEnumerable` is more general than accepting an array. I think we'd have to see the body of the method to see whether it's doing anything which is enabled by generics, but not by an array – canton7 Aug 02 '21 at 08:37
  • Also bear in mind that an `IEnumerable` typically involves a cursor, not the actual data set. Imagine a multi-million records data source. If you write the copy requiring an array, then will be problematic to istantiate such as array. Instead, the cursor permits to scan an arbitrary-size collection without loading anything more than a single record. – Mario Vernari Aug 02 '21 at 08:39
  • All valid remarks about the array and IEnumerable. But the question is about T vs DataRow. In this case it would be `DataTable CopyToDataTable(this IEnumerable source)` as @Cleptus suggested. – XWIKO Aug 02 '21 at 08:44
  • @canton7 I think I did not find anything enabled by the Generic. It even typed it back to a DataRow inside. Line 148-151. https://referencesource.microsoft.com/#System.Data.DataSetExtensions/System/Data/DataTableExtensions.cs,f13583ec86a5fe61 – XWIKO Aug 02 '21 at 08:52
  • 1
    So, there's an advantage in taking an `IEnumerable` rather than an array: what if the caller has a list rather than array, or something else which is an `IEnumerable` but not an array. The input doesn't *need* to be an array, it just needs to be enumerable, so accepting an `IEnumerable` is more flexible. I think it could happily take an `IEnumerable` due to covariance, but that was only introduced in C#4, and it's quite possible that this code predates that – canton7 Aug 02 '21 at 08:58
  • https://stackoverflow.com/a/68619005/259769 – Enigmativity Aug 02 '21 at 09:08
  • 2
    @Enigmativity That doesn't answer this specific case, however. We're not adding to a collection of `T`, just a collection of `DataRow` – canton7 Aug 02 '21 at 09:13
  • 2
    @Enigmativity This question is not a dupe of the one you've linked to. – John H Aug 02 '21 at 09:14

1 Answers1

8

I think there are two parts to this.

The first is that accepting an IEnumerable is more flexible than accepting an array. What if the user has a List<DataRow>, or some other collection type? What if they want to pass the result of a linq query? Accepting an array forces them to allocate a new array just to pass to CopyToDataTable, and that's unnecessary cost.

There's no reason why CopyToDataTable needs an array: it just needs an IEnumerable. So it's best if it just accepts an IEnumerable.

That said, due to covariance it would be possible to use the signature:

DataTable CopyToDataTable(this IEnumerable<DataRow> source)

... and users would be able to pass e.g. an IEnumerable<TableDetailsRow> (where TableDetailsRow extends DataRow). However, covariance was only introduced in C# 4, and that method has been around since .NET 3.5, which means it was probably written in C# 3. Since covariance wasn't available then, generics was the next best thing.

canton7
  • 37,633
  • 3
  • 64
  • 77