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) {
    //...
}