2013-03-15 2 views
1

У меня есть класс RepositoryBase, где я определяю базовые методы crud для моего Контекста Entity Framework. У меня есть эти два перегруженных метода All():Вывод типа в методах репозитория

public virtual IQueryable<T> All<TKey>(Expression<Func<T, bool>> predicate) 
{ 
    return All().Where(predicate); 
} 

public virtual PagedResult<T> All<TKey>(int startRowIndex, int maximumRows, 
    Expression<Func<T, TKey>> orderingKey, Expression<Func<T, bool>> predicate, 
    bool sortDescending = false) 
{ 
    var subset = All().Where(predicate); 

    IEnumerable<T> result = sortDescending 
           ? subset.OrderByDescending(orderingKey).Skip(startRowIndex).Take(maximumRows) 
           : subset.OrderBy(orderingKey).Skip(startRowIndex).Take(maximumRows); 

    //More code ommited 
} 

Первый метод всегда нуждается во мне явно указать тип объекта, а второй нет. Почему это?

Пример, это не компилируется:

return All(s => s.LoanApplicationId == loanApplicationId) 

И вместо этого я должен назвать это так:

return All<LoanApplication>(s => s.LoanApplicationId == loanApplicationId) 

Но это скомпилировать:

return All(0,10, s => s.Name, s => s.LoanApplicationId == loanApplicationId, false) 

ответ

2

TKey в список параметров второго (через Expression<Func<T, TKey>> orderingKey), а не первый. Это достаточно для второго, чтобы успешно вывести тип, когда вы используете его с указанными вами аргументами (s => s.Name). Вы не даете себе такую ​​роскошь в первой версии, поэтому компилятор заставляет вас заполнять детали, явно указывая параметр типа.

И по внешнему виду, в любом случае вам не нужно TKey, так что, возможно, избавитесь от него (если только не видно больше кода, чем эта относительно простая реализация). И я не думаю, что это означает, что ваш образец вызова считает, что это значит. TKey во втором, скорее всего, string (независимо от типа s.Name), например.