Shuzheng
Shuzheng

Reputation: 14018

How can I call a function expecting `params T[]` arguments given an `IEnumerable<T>`?

How can I call a function expecting param T[] arguments given an IEnumerable<T>?

Consider the following function signature:

public async Task AddNotificationRecordsAsync(
               IEnumerable<NotificationRecord> notificationRecords,
               CancellationToken cancellationToken = default)

In this function, I want to call the following EF Core function:

void DbSet<NotificationRecord>.AddRange(params NotificationRecord[] entities)

However, I don't know how to convert the IEnumerable into separate params.

In Python, I would use the unpacking operator "*" as follows: f(*mylist).

Upvotes: 1

Views: 88

Answers (1)

wohlstad
wohlstad

Reputation: 29009

How can I call a function expecting param T[] arguments given an IEnumerable?

The param keyword allows you to pass an array as separate parameters. But it does not prohibit you to pass a regular array.

This is demonstrated in this example:

using System;
                    
public class Program
{
    static void f(params int[] vals)
    {
        foreach (int val in vals) Console.Write(val + ",");
        Console.WriteLine("");
    }

    public static void Main()
    {
        f(1, 2, 3);  // works
        f(new int[3] { 1, 2, 3 }); // also works
    }
}

Live demo

Therefore you can use Enumerable.ToArray method to convert IEnumerable<T> to T[] and pass it to a method expecting a param T[]:

public async Task AddNotificationRecordsAsync(IEnumerable<NotificationRecord> notificationRecords, CancellationToken cancellationToken = default)
{
   // ...

   //---------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvv--
   DbSet<NotificationRecord>.AddRange(notificationRecords.ToArray());
}

A side note:
In this specific case, as @shingo commented, DbSet<TEntity>.AddRange also has an overload that accepts IEnumerable<TEntity>. Therefore you could have passed notificationRecords as is.

Upvotes: 4

Related Questions