Как найти тип, который выводит linq, в тип возвращаемого значения функции - PullRequest
1 голос
/ 24 января 2020

У меня есть функция, которая выглядит следующим образом:

 Task<IEnumerable<User>> GetUserContactInfo(
            CancellationToken cancellationToken = new CancellationToken()
               )
        {
                var users = from u in _userDbContext.Users
                        join ur in _userDbContext.UserRoles on u.Id equals ur.UserId
                        select u;
            var u2 = users.ToListAsync(cancellationToken).ConfigureAwait(false);

            return u2;

        }

, но .. попытка скомпилировать дает мне эту ошибку:

Ошибка CS0029 Не удается неявно преобразовать тип 'System.Runtime.CompilerServices.ConfiguredTaskAwaitable<System.Collections.Generic.List <IPD.Identity.Domain.Aggregates.UserAggregate.User>>' to 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<IPD.Identity.Domain.Aggregates.UserAggregate.User>>'

Есть какие-нибудь идеи о том, как привести в тип возвращаемого значения функции или поочередно присоединить что-нибудь к linq, которое вернет правильный тип, или действительно какие-либо другие идеи?

1 Ответ

4 голосов
/ 24 января 2020

ConfigureAwait возвращает ConfiguredTaskAwaitable, а не Task. Вам нужно явно ожидать этого с ключевым словом await и изменить этот метод на async.

Но вы также можете просто вернуть Task без ConfigureAwait(false), и в этом случае ничего не нужно чтобы сделать это отдельно, добавив ConfigureAwait() к вызывающему методу.

Итак, просто верните users.ToListAsync(cancellationToken); из этого метода и вызовите его так:

var info = await GetUserContactInfo(token).ConfigureAwait(false);

В этом случае, как вы не используя await внутри этого метода, нет необходимости в ConfigureAwait после ToListAsync().

Обновление для комментария:

Кстати, так как тип возвращаемого значения - Task<IEnumerable<...>, вы не сможете вернуть Task<List<...>>. Потому что Task<> не является ковариантным типом. Для решения этой проблемы вы можете изменить тип возвращаемого значения на Task<List<...>>.

Таким образом, результат может быть таким:

Task<List<User>> GetUserContactInfo(CancellationToken cancellationToken = new CancellationToken())
        {
            var users = from u in _userDbContext.Users
                        join ur in _userDbContext.UserRoles on u.Id equals ur.UserId
                        select u;
            return users.ToListAsync(cancellationToken);
        }
...