2015-01-06 112 views
1

我真的很困惑這裏。你能幫我麼?查看代碼;類型參數'T'與來自外部類型的類型參數具有相同的名稱'...

我想爲我的解決方案構建一個只使用一個存儲庫的結構。要查詢我使用IQueryBuilder的特定查詢。其實我一直在尋找一個好的smaple爲對象查詢和我發現這一個here

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」具有相同的名稱從外型「IRepository」 IRepository.cs 13 32 VideoK2.Repository

通過有關於這個話題的一些問題的方式,類型參數。但我無法理解他們。無法弄清楚我的話題。所以,很抱歉再次提問。

+1

從根本上講,「子」的一個定義了一個黑影從超泛型類型的名稱。從本質上講,它增加了含糊不清的名字'T'。 –

+0

這是C#嗎?如果是這樣,請將該標籤添加到您的問題中。 –

回答

5

此代碼:

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

保留兩個泛型參數沒有太大的意義在這種情況下,因爲一個他們從未使用過。

9

編譯器看到這一定義含糊:

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(); 
} 
+2

編譯器絕對不會混淆,但用戶是;)無論如何,很好的解釋。 –

0

好的。在我看到正確答案後的答案。我使用通用存儲庫和對象查詢的原因是我想爲所有查詢使用一個存儲庫。所以這迫使我使用Generic Repository。 (因爲我以前的練習)。但是在這個示例中使用通用存儲庫不是必需的。

我想寫一些代碼的更多信息。

此界面對象查詢

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); 
    } 
} 
相關問題