类型参数 'T' 与外部类型 '....

本文关键字:类型 外部 类型参数 | 更新日期: 2023-09-27 18:36:42

我在这里真的很困惑。你能帮帮我吗?查看代码;

我正在尝试为我的解决方案构建一个仅使用一个存储库的结构。为了查询特定的查询,我使用IQueryBuilder。实际上,我一直在寻找一个用于对象查询的好smaple,我在这里找到了这个

public interface IQueryBuilder<T> where T : class
{
    IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate);
    IQueryBuilder<T> Include(Expression<Func<T, object>> path);
    IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path);
    IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path);
    IQueryBuilder<T> Page(int page, int pageSize);
    T FirstOrDefault();
    Task<T> FirstOrDefaultAsync();
    List<T> ToList();
    Task<List<T>> ToListAsync();
    int Count();
    Task<int> CountAsync();
}

存储库代码在此处。

public interface IRepository<T> : IDisposable
{
    IQueryBuilder<T> Query<T>() where T : class;
}

到目前为止,对我来说很好。我非常非常高兴,直到按 F6 并且由于存储库界面中的查询而出现以下错误。

警告 1 类型参数"

T"与外部类型"独立"中的类型参数同名.cs 13 32 视频K2.存储库

顺便说一下,关于这个话题有几个问题。但我无法理解他们。无法弄清楚我的话题。所以,很抱歉再次询问。

类型参数 'T' 与外部类型 '....

编译器认为此定义不明确:

public interface IRepository<T> : IDisposable
{
    IQueryBuilder<T> Query<T>() where T : class;
}

要了解原因,请问自己这个示例问题(我将使用两个随机选择的类):如果你有一个IRepository<string>实例,你应该能够调用Query<StreamReader>吗?

如果答案是肯定的,则意味着方法 Query<T> 的类型参数T与接口IRepository<T>的类型参数T不同。它们是两个独立的类型参数。如果是这种情况,那么只需将两者之一更改为其他内容,以明确您的意图:

public interface IRepository<T> : IDisposable
{
    IQueryBuilder<TResult> Query<TResult>() where TResult : class;
}

如果答案是否定的,则表示接口IRepository<T>的类型参数T指示方法Query的返回类型。如果是这种情况,则该方法不应声明自己的类型参数,因为类型已具有信息。

public interface IRepository<T> : IDisposable 
    where T : class
{
    IQueryBuilder<T> Query();
}

此代码:

public interface IRepository<T> : IDisposable
{
    IQueryBuilder<T> Query<T>() where T : class;
}

基本上可以改写为:

public interface IRepository<TObject> : IDisposable
{
    IQueryBuilder<TResult> Query<TResult>() where TResult : class;
}

摆脱错误。问题是第二个<T>掩盖了第一个。

但是......你看到这个新代码的问题了吗?


我想你真正的意思是:

public interface IRepository<T> : IDisposable
    where T : class
{
    IQueryBuilder<T> Query();
}

或者这个:

public interface IRepository : IDisposable
{
    IQueryBuilder<T> Query<T>() where T : class;
}

在这种情况下,保留这两个泛型参数没有多大意义,因为从不使用其中一个参数。

好的。在回答之后,我看到了正确的方法。我使用通用存储库和对象查询的原因是我想对所有查询使用一个存储库。所以这迫使我使用通用存储库。(因为我以前的练习)。但在此示例中,不需要使用通用存储库。

我想为进一步的信息编写一些代码。

此接口用于对象查询

public interface IQueryBuilder<T>
{
    IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate);
    IQueryBuilder<T> Include(Expression<Func<T, object>> path);
    IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path);
    IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path);
    IQueryBuilder<T> Page(int page, int pageSize);
    T FirstOrDefault();
    Task<T> FirstOrDefaultAsync();
    List<T> ToList();
    Task<List<T>> ToListAsync();
    int Count();
    Task<int> CountAsync();
}

及其实施

public class QueryBuilder<T> : IQueryBuilder<T>
{
    DdContext applicationDbContext;
    private IQueryable<T> query;
    public QueryBuilder(DbContext applicationDbContext)
    {
        this.applicationDbContext = applicationDbContext;
        this.query = this.context.Set<T>();
    }
    public IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate)
    {
        this.query = this.query.Where(predicate);
        return this;
    }
    public IQueryBuilder<T> Include(Expression<Func<T, object>> path)
    {
        this.query = this.query.Include(path);
        return this;
    }
    public IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path)
    {
        this.query = this.query.OrderBy(path);
        return this;
    }
    public IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path)
    {
        this.query = this.query.OrderByDescending(path);
        return this;
    }
    public IQueryBuilder<T> Page(int page, int pageSize)
    {
        this.query = this.query.Skip(page * pageSize).Take(pageSize);
        return this;
    }
    public T FirstOrDefault()
    {
        return this.query.FirstOrDefault<T>();
    }
    public Task<T> FirstOrDefaultAsync()
    {
        return this.query.FirstOrDefaultAsync();
    }
    public List<T> ToList()
    {
        return this.query.ToList();
    }
    public Task<List<T>> ToListAsync()
    {
        return this.query.ToListAsync();
    }
    public int Count()
    {
        return this.query.Count();
    }
    public Task<int> CountAsync()
    {
        return this.query.CountAsync();
    }
}

这是存储库界面

public interface IRepository
{
    IQueryBuilder<T> Query<T>();
}

及其实施

public class Repository : IRepository
{
    private DBContext Contex { get; set; }
    public Repository(DBContext ctx)
    {
        this.Contex = ctx;
    }
    public QueryBuilder.IQueryBuilder<T> Query<T>()
    {
        return new QueryBuilder.QueryBuilder<T>(this.Contex);
    }
}

这些行是示例用法

public class HomeController : Controller
{
    private IRepository repo = new Repository(new SampleContext());
    public HomeController(){}
    // GET: Home
    public ActionResult Index()
    {
        var author = repo.Query<Author>().ToList();
        var authors = repo.Query<Author>().ToListAsync();
        var authors = repo.Query<Author>().Where(a => a.Name != "Orwell").ToList();
        var authors = repo.Query<Author>().Where(a => a.Name != "Orwell").ToListAsync();
        var author = repo.Query<Author>().FirstOrDefault();
        var author = repo.Query<Author>().FirstOrDefaultAsync();
        var author = repo.Query<Author>().Where(a => a.Name == "Orwell").FirstOrDefault();
        var author = repo.Query<Author>().Where(a => a.Name == "Orwell").FirstOrDefaultAsync();
        var book = repo.Query<Book>().Where(b => b.Title == "The Wasp Factory").FirstOrDefault();
        return View(author);
    }
}