Search code examples
c#functiontypestypeerror

Issues with concatenating after Array.Select in C#


I'm working on the following code for a uni project:

public Order[] collapse()
{
    return ConcatArrays(Rondes.Select(rs => rs.collapse()));
}

public static T[] ConcatArrays<T>(T[][] list)
{
    var result = new T[list.Sum(a => a.Length)];
    int offset = 0;
    for (int x = 0; x < list.Length; x++)
    {
        list[x].CopyTo(result, offset);
        offset += list[x].Length;
    }
    return result;
}

Here rs is of a custom type Ronde, and rs.collapse() returns Order[]. The goal of the first function is to compute rs.collapse() for every rs, and concatenate these arrays. How do I resolve the following error:

The type arguments for method ConcatArrays<T>(T[][]) cannot be inferred from the usage. Try specifying the type arguments explicitly.

I tried to follow the reccomendation by changing all T's to Order, but that did not change the error message. Any help is greatly appreciated!! Thanks in advance!

EDIT: I have now changed the first function to:

public Order[] collapse()
    {
        if (Rondes == null) { return new Order[0]; }
        return OrderLijsten.ConcatArrays<Order>(Rondes.Select(rs => rs.collapse()));
    }

but now i get this error:

Error   CS1503  Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<Grote_Opdracht.Classes.Order[]>' to 'Grote_Opdracht.Classes.Order[][]'


Solution

  • The error message gives you a pretty clear explanation: Your Select call returns an IEnumerable but this ConcatArrays implementation expects an array (of arrays).

    You could either make the method use IEnumerable (but then you would enumerate multiple times), or call ToArray to make an array. In this case, I would prefer a combination, and also use ToList instead, which should be the most performant option:

    public Order[] Collapse()
    {
        // make sure to iterate only once
        var arrays = Rondes.Select(rs => rs.collapse()).ToList();
        return ConcatArrays(arrays);
    }
    
    // use IEnumerable to be more flexible
    public static T[] ConcatArrays<T>(IEnumerable<T[]> arrays)
    {
        var result = new T[arrays.Sum(a => a.Length)];
        int offset = 0;
        foreach (var a in arrays)
        {
            a.CopyTo(result, offset);
            offset += a.Length;
        }
        return result;
    }