Home > Software design >  return a list of generic C#
return a list of generic C#

Time:08-05

I have a singleton class, holding several list of data. I want to have a function to return one of the list based on the requested data type

public class Book
{
    public string Name { get; set; }
    public int Pages { get; set; }
}

public class DVD
{
    public string Name { get; set; }
    public TimeSpan Length { get; set; }
}

public class DBReferenceSingleton
{
    private List<Book> _bookList;
    private List<DVD> _dvdList;

    public IEnumerable<Entity> GetEntities<Entity>() where Entity : class
    {
        switch(typeof(Entity).Name)
        {
            case nameof(Book):
                return _bookList;
            case nameof(DVD):
                return _dvdList;
        }
        return null;
    }

This is not working, since a conversion is needed. I wonder if there is any elegant solution (without serialize all elements or implement IConvertible)?

CodePudding user response:

It doesn't look like generics seem the right tool here; not least because Book and DVD don't have a common base class.

I think you should have two methods:

public List<Book> GetBooks() => _bookList;
public List<DVD> GetDvds() => _dvdList;

CodePudding user response:

Have you tried doing a Cast?

public class Book
{
    public string Name { get; set; }
    public int Pages { get; set; }
}

public class DVD
{
    public string Name { get; set; }
    public TimeSpan Length { get; set; }
}

public class DBReferenceSingleton
{
    private List<Book> _bookList;
    private List<DVD> _dvdList;

    public IEnumerable<Entity> GetEntities<Entity>() where Entity : class
    {
        switch(typeof(Entity).Name)
        {
            case nameof(Book):
                return _bookList as List<Entity>;
            case nameof(DVD):
                return _dvdList as List<Entity>;
        }
        return null;
    }
}

the "as List< Entity >" will return null if the object is the wrong type, or the object as the type if it's the right type. The A = B as C pattern works for inherited types as well, just remember to check for null returned values for cases where your type isn't as well known as in this situation

A side comment on the usefulness of having a generic method in this case: In this method you're forced to set the type of entity each time explicitly, which means your method is functionally non-generic - so you might as well make two explicit methods.

One case where a generic method like the one you have might be more useful, is if book and dvd both inherited from a base class, and you had some follow up methods that needed to operate off a list of . For example, you might end up wanting to do something like this instead in your code:

public class Book : Rentable
{
    public int Pages { get; set; }
}
public class DVD : Rentable
{
    public TimeSpan Length { get; set; }
}
public class Rentable
{
    public string Name { get; set; }
    public string borrowedBy { get; set; }
}
public class DBReferenceSingleton
{
    private List<Book> _bookList;
    private List<DVD> _dvdList;
    public enum RentableType { Book, DVD }
    public IEnumerable<Rentable> GetEntities(RentableType entityType)
    {
        switch (entityType)
        {
            case RentableType.Book:
                return _bookList.ToList<Rentable>();
            case RentableType.DVD:
                return _dvdList.ToList<Rentable>();
            default:
                throw new NotImplementedException($"Entity {entityType} not supported");
        }
        return null;
    }
}
  • Related