A while back I wrote a method that takes an array of data that I use for inserting records into a database:
public Promise<int[]> InsertOrReplaceAsync(string table, Dictionary<string, object>[] records) {
//...
}
An annoying issue is in some parts of my code the records are a List instead of an array, so I have to call it like this:
var p = InsertOrReplaceAsync("tableName", records.ToArray());
ToArray creates a copy of the data which can eventually trigger the garbage collector (my application is extremely sensitive to garbage collection). So I was looking for a better solution.
One option would be to create a complete copy of my InsertOrReplaceAsync method: one for arrays, and one for lists. This is a poor option since duplicated code makes things more difficult to debug and maintain.
Next I considered replacing the array parameter with the IEnumerable interface:
public Promise<int[]> InsertOrReplaceAsync(string table, IEnumerable<Dictionary<string, object>> records) {
//...
}
Now my method will accept either array or lists, in addition to various other enumerable types.
But this isn’t quite the best solution in my case. The problem is I need to be able to get the count of items before iterating through the list.
C# lists can return the number of elements with the Count property. C# arrays also can return their number of elements with the Length property. But if you pass a list or array as an IEnumerable then the count or length will be lost.
It turns out that both Arrays and Lists implement another interface: ICollection.
ICollection is very similar to IEnumerable, with the added benefit that it also has a Count property. This allows me to get the count of items in the collection without iterating over it first.
public Promise<int[]> InsertOrReplaceAsync(string table, ICollection<Dictionary<string, object>> records) {
//...
}