我正在练习如何使用C#创建开闭原理以返回信息列表。但是问题是我的主服务类出现错误。
这些是我的示例代码:
我有这个界面:
public interface ISelectInfo{
bool Rule(string rule);
IQueryable<FoodDto> ReturnSearchResult(string query);
}
我有实现此接口的此类。
public class Fruit : ISelectInfo {
public bool Rule(string rule){
return "fruit".Equals(rule);
}
public IQueryable<FoodDto> ReturnSearchResult(string query){
// returns a list of FoodDto
}
}
我有这个主要的服务班
public class SelectTypeOFoodService {
private readonly IList<ISelectInfo> selectInfo;
public SelectTypeOfFruitService (IList<ISelectInfo> selectInfo){
this.selectInfo = selectInfo;
}
public async IEnumerable<FoodDto> SelectFood(string rule, string query){
return await selectInfo.ToList().Where(x=>x.Rule(rule)).Select(x=>x.ReturnSearchResult(query)).AsQueryable().TolistAsync();
}
}
我的return await selectInfo.ToList()...
上出现错误和红色的波浪线
我要实现的目标是将FoodD列表返回到基于开放式封闭原则的
。这是显示Cannot convert expression type 'System.Collections.Generic.List<System.Linq.IQueryable<FoodDto>>' to return type 'System.Collections.Generic.IEnumerable<FoodDto>'
的红色波浪线的示例结果
我希望有人能帮助我。
答案 0 :(得分:1)
或者,您可以在 LayoutInflater layoutInflaterAndroid = LayoutInflater.from(this);
View mView =
layoutInflaterAndroid.inflate(R.layout.activity_login2,null);
final AlertDialog.Builder alertDialogBuilderUserInput = new
AlertDialog.Builder(this,R.style.AlertDialogTheme);
final EditText userInputDialogEditText = (EditText)
mView.findViewById(R.id.userInputDialog);
alertDialogBuilderUserInput.setView(mView);
AlertDialog alertDialogAndroid = alertDialogBuilderUserInput.create();
alertDialogAndroid.show();
alertDialogAndroid.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// TODO Do something
if(userInputDialogEditText.getText().toString().equals("")){
userInputDialogEditText.setError("Enter Username");
}else {
String username =
userInputDialogEditText.getText().toString();
editor.putString("USERNAME",username);
editor.apply();
tV2.setText(username);
dialog.dismiss();
}
}
});
}
});
alertDialogAndroid.show();
上使用async
,在下面检查我的重构代码。
IQueryable<FoodDto
为您服务
public class Fruit : ISelectInfo {
public bool Rule(string rule){
return "fruit".Equals(rule);
}
public async Task<IEnumerable<FoodDto>> ReturnSearchResult(string query){
// returns a list of FoodDto
}
}
此外,不要忘记在中间件或启动类上注册接口和类。
希望这对其他人也有帮助。
答案 1 :(得分:1)
我总是想知道为什么提问者会给出一些代码并说在没有给出确切要求的情况下该代码不起作用。
在我看来,您想向类SelectTypeOFoodService
添加一个异步函数,该函数需要两个参数作为输入:string rule
和string query
。
输出应该是ReturnSearchResult(query)
中所有具有this.selectInfos
的真实返回值的项目中的this.selectInfos.Rule(rule)
注意:我可以自由地对您的馆藏标识符进行复数处理,因为这样可以简化答案的阅读。
可能是您简化了需求,但在我看来,您不需要异步功能。
IQueryable<FoodDto> QueryFood(string rule, string query)
{
return this.selectInfos
.Where(selectInfo => selectInfo.Rule(rule))
.Select(selectInfo => selectInfo.ReturnSearchResult(query);
}
IEnumerable<FootDto> SelectFood(string rule, string query)
{
return this.QueryFood(rule, query).AsEnumerable();
}
我选择使用AsEnumerable
而不是ToList
,因为显然您想返回一个IEnumerable
。如果您的呼叫者在致电FirstOrDefault
之后使用SelectFood
,那么将您所有的1000种食物都转换成一个列表,然后只使用第一个就浪费了。
例如,如果由于要放置可查询对象而确实需要调用ToList,请考虑返回List
而不是IEnumerable
。这样可以防止用户拨打额外的ToList
,从而导致您商品的第二次列出。
List<FoodDto> SelectFood(string rule, string query)
{
return this.QueryFood(rule, query).ToList()
}
现在,创建异步版本可能是有意义的,因为ToList是实际上将执行查询的功能,并且如果要通过等待的过程(例如数据库查询,互联网获取数据,文件读取),那么创建异步功能可能很有意义:
Task<List<FoodDto>> SelectFoodAsync((string rule, string query)
{
return this.QueryFood(rule, query).ToListAsync();
}
再一次:如果没有什么可等待的,请不要在类中引入async-await,这只会使您的代码效率降低。
有时候,您的类没有什么可等待的,但是您确实需要创建一个异步函数,例如,实现一个返回Task的接口,或者在单元测试中模拟功能以测试使用async-await的功能
在这种情况下,让async函数调用sync函数并使用Task.FromResult
组成返回值
Task<List<FoodDto>> SelectFoodAsync((string rule, string query)
{
List<FoodDto> selectedFoods = this.SelectFoods(rule, query);
return Task.FromResult(selectedFoods);
}