简体   繁体   English

返回通用 C# 的列表

[英]return a list of generic C#

I have a singleton class, holding several list of data.我有一个 singleton class,包含几个数据列表。 I want to have a function to return one of the list based on the requested data type我想要一个 function 根据请求的数据类型返回列表之一

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)?我想知道是否有任何优雅的解决方案(不序列化所有元素或实现 IConvertible)?

It doesn't look like generics seem the right tool here;看起来 generics 似乎不是这里的正确工具; not least because Book and DVD don't have a common base class.尤其是因为BookDVD没有共同的基础 class。

I think you should have two methods:我认为你应该有两种方法:

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

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.如果 object 类型错误,“as List< Entity >”将返回 null,如果类型正确,则返回 object 作为类型。 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 = B as C 模式也适用于继承类型,只要记住检查 null 返回的值,以防您的类型不像在这种情况下那样广为人知

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.像您所拥有的通用方法可能更有用的一种情况是,如果 book 和 dvd 都从基础 class 继承,并且您有一些后续方法需要从列表中操作。 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM