使用 C# 中的给定类型参数返回列表

本文关键字:类型参数 返回 列表 使用 | 更新日期: 2023-09-27 18:33:08

问题如下:我有一个方法(应该)返回具有给定类型参数的不同列表。这是代码:

public IEnumerable<T> GetList<T>() {
    if (typeof(T) == typeof(Account))
        return GetList().Select(m => m.Coordinator).Distinct();
    else if (typeof(T) == typeof(Blok))
        return null;
    else if (typeof(T) == typeof(Curriculum))
        return null;
     else if (typeof(T) == typeof(Program))
        return null;
    return null;
}

对于大多数人来说,错误是显而易见的:"无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'System.Collections.Generic.IEnumerable"。存在显式转换(您是否缺少强制转换?这意味着强制转换解决了问题,例如("(IEnumerable)"或"as IEnumerable"),但这是要走的路吗?解决这个问题的优雅方法是什么?

使用 C# 中的给定类型参数返回列表

您可以通过简单地按照错误消息进行强制转换来做到这一点

return GetList().Select(m => m.Coordinator).Distinct() as IEnumerable<T>;

这可以通过简单地使用接口通过通用存储库来完成。实现此存储库的类是否进入数据库并不重要。

public interface IRepository<TEntity>
{
    IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "");
    TEntity GetById(object id);
    void Insert(TEntity entity);
    void Delete(object id);
    void Delete(TEntity entityToDelete);
    void Update(TEntity entityToUpdate);
}

使用实体框架的示例实现:(在这里使用 EF 还是只是模型类并不重要,您只需将上下文/实体替换为例如列表)

public class Repository<TEntity> : IRepository<TEntity>, IDisposable where TEntity : class
{
    internal ApplicationContext Context;
    internal DbSet<TEntity> Entities;
    public Repository(ApplicationContext context)
    {
        if (Context == null)
        {
            throw new ArgumentNullException();
        }
        Context = context;
        Entities = Context.Set<TEntity>();
    }
    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = Entities;
        if(filter != null)
        {
            query = query.Where(filter);
        }
        query = includeProperties.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
            .Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
        return orderBy != null ? orderBy(query).ToList() : query.ToList();
    }
    public virtual TEntity GetById(object id)
    {
        return Entities.Find(id);
    }
    public virtual void Insert(TEntity entity)
    {
        Entities.Add(entity);
    }
    public virtual void Delete(object id)
    {
        TEntity entityToDelete = Entities.Find(id);
        Delete(entityToDelete);
    }
    public virtual void Delete(TEntity entityToDelete)
    {
        if (Context.Entry(entityToDelete).State == EntityState.Detached)
        {
            Entities.Attach(entityToDelete);
        }
        Entities.Remove(entityToDelete);
    }
    public virtual void Update(TEntity entityToUpdate)
    {
        Entities.Attach(entityToUpdate);
        Context.Entry(entityToUpdate).State = EntityState.Modified;
    }