[英]How can I append a call to an extension method on a call to an async method
I have a custom extension method "ToSelectList" and I am currently using it like so: 我有一个自定义扩展方法“ ToSelectList”,目前正在使用它,如下所示:
var myList = await _myService.GetItems();
var mySelectList = myList.ToSelectList(nameof(MyEntity.Id));
That's fine and works great, however, I tried to do this as one line: 很好,效果很好,但是我尝试将其作为一行:
var myList = await _myService.GetItems().ToSelectList(nameof(MyEntity.Id));
But I get: 但是我得到:
'Task<List<MyEntity>>' does not contain a definition for 'ToSelectList'
and no extension method 'ToSelectList' accepting a first argument of type
'Task<List<MyEntity>>' could be found (are you missing a using directive
or an assembly reference?)
My ToSelectList method is as follows: 我的ToSelectList方法如下:
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace MyProject.Extensions
{
public static class ListExtensions
{
public static List<SelectListItem> ToSelectList<T>(this List<T> list, string id, string text = "Name")
{
var selectListItems = new List<SelectListItem>();
list.ForEach(item =>
{
selectListItems.Add(new SelectListItem
{
Text = item.GetType().GetProperty(text).GetValue(item).ToString(),
Value = item.GetType().GetProperty(id).GetValue(item).ToString()
});
});
return selectListItems;
}
}
I tried changing method signature to public async static Task<List<SelectListItem>>
but no joy. 我尝试将方法签名更改为
public async static Task<List<SelectListItem>>
但没有任何乐趣。
The problem is that await
applies to the entire line so you either need to wrap it in parentheses: 问题是,
await
应用于整行,因此您需要将其包装在括号中:
var myList = (await _myService.GetItems())
.ToSelectList(nameof(MyEntity.Id));
Or split it onto 2 lines: 或将其分为两行:
var items = await _myService.GetItems();
var myList = items.ToSelectList(nameof(MyEntity.Id));
While @DavidG 's answer is correct, I would suggest you to simplify your logic. 虽然@DavidG的答案是正确的,但我建议您简化逻辑。 You don't need any of that reflection code if you use the built-in
Tuple<T1, T2>
: 如果使用内置的
Tuple<T1, T2>
则不需要任何反射代码:
// let's assume this is in your service class
// you most likely want a better name
public Task<List<Tuple<int, string>>> GetItemsAsEnumAsync()
{
return _context.SomeTable
.Select(x => Tuple.Create(x.Id, x.Name))
.ToListAsync();
}
Your ToSelectList
would then just be: 您的
ToSelectList
将会是:
public static List<SelectListItem> ToSelectList(this List<Tuple<int, string>> list)
{
return list
.Select(x => new SelectListItem
{
Value = x.Item1.ToString(),
Text = x.Item2
})
.ToList();
}
This assumes that your service is not in the same project as the ASP.NET Core application and hence cannot return the List<SelectListItem>
itself. 这假定您的服务与ASP.NET Core应用程序不在同一个项目中,因此无法返回
List<SelectListItem>
本身。 You could make ToSelectList
more generic by using ToSelectList<T1, T2>(this List<KeyValuePair<T1, T2>> list)
if you find it useful. 如果发现有用,可以使用
ToSelectList<T1, T2>(this List<KeyValuePair<T1, T2>> list)
使ToSelectList
更通用。
You can either go for: 您可以选择:
var myList = _myService.GetItems().Result.ToSelectList(nameof(MyEntity.Id));
but this will just block the thread and you will execute code non async 但这只会阻塞线程,您将执行非异步代码
or change result of _myService.GetItems()
to List<SelectListItem>
. 或将
_myService.GetItems()
结果更改为List<SelectListItem>
。
Anyway what is the point of this async if you immediately need the result? 无论如何,如果您立即需要结果,那么异步的意义是什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.