Getting List<T> from object[] in generic method

46 Views Asked by At

I'm trying to write a method that gathers all the results of paginated API calls for any type into a list. My method looks like this so far...

        private async Task<List<T>> AggregateResults<T>(string url)
        {
            var results = new List<T>();

            var morePages = true;
            while (morePages)
            {
                var response = await _httpClient.GetAsync(url);
                var responseContent = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject<PaginatedResult>(responseContent);

                results.AddRange(result.results.Cast<T>().ToList());

                if (result.paging != null)
                {
                    url = result.paging.next.link;
                }
                else
                {
                    morePages = false;
                }
            }
            return results;
        }

the Paginated Result class looks like this

{
    public class PaginatedResult
    {
        public object[] results { get; set; }
        public Paging? paging { get; set; }
    }

    public class Paging
    {
        public Next next { get; set; }
    }

    public class Next
    {
        public string after { get; set; }
        public string link { get; set; }
    }
}

And I'm passing in things like this as the generic for the method

public class Person
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
}

I'm getting this error right now 'Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type . Is there any way I can get a List from an object[] here?

I've tried casting the array about any way I can find and keep running into errors. I've thought about inheriting from PaginatedResult in my classes that I'm trying to get in lists, but can't wrap my head around how that would work or if it would.

1

There are 1 best solutions below

1
Janilson On BEST ANSWER

Try making PaginatedResult a generic class PaginatedResult<T>, and change results type from object[] to T[]. You can then just AddRange(result.results), no need to use Cast<T> or call ToList

using Newtonsoft.Json;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            const string j = """
{
    "results": [
        { "name": "a", "DateOfBirth": "2000/01/01" },
        { "name": "b", "DateOfBirth": "2000/01/01" },
    ],
    "paging" : {
        "next": {
            "after": "...",
            "link": "..."
        }
    }
}
""";
            var res = JsonConvert.DeserializeObject<PaginatedResult<Person>>(j);
            Console.WriteLine(res.results[0].Name);
        }

        public class PaginatedResult<T>
        {
            public T[] results { get; set; }
            public Paging? paging { get; set; }
        }

        public class Paging
        {
            public Next next { get; set; }
        }

        public class Next
        {
            public string after { get; set; }
            public string link { get; set; }
        }
        public class Person
        {
            public string Name { get; set; }
            public DateTime DateOfBirth { get; set; }
        }
    }
}