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;
}
}