在while循环中使用yield返回一个或多个对象

本文关键字:一个 对象 返回 循环 while yield | 更新日期: 2023-09-27 18:20:02

我有两个数据库方法。一个基于名称提取一行并从中创建一个对象。另一个几乎相同,但它提取所有行并从其中创建n对象。我希望使用yield return来共享处理SQLLite数据的方法,但我在CreateFooFromSQLSelect中遇到的问题告诉我The body of CreateFooFromSQLSelect cannot be an iterator block because Foo is not an iterator type。我真的没想到。

public Foo GetFoo(string name){
   string sql = "SELECT age FROM people WHERE name = " + name;
   return CreateFooFromSelect(sql);
}
public List<Foo> GetFoos(){
   List<Foo> foos = new List<Foo>();
   string sql = "SELECT * FROM people";
   foos.Add(CreateFooFromSelect(sql));
}
private Foo CreateFooFromSelect(string sql){
   Foo foo;
   SQLiteCommand command = new SQLiteCommand(sql, sqlConnection);
   SQLiteDataReader reader = command.ExecuteReader();
   while(reader.Read()){
        yield return foo = new Foo(reader["age"]);
   }
}

在while循环中使用yield返回一个或多个对象

只能在返回IEnumerable<T>的方法上使用yield语句。在您的例子中,方法返回Foo,所以您不能在那里使用yield语句。相反,你可以尝试这样的方法:

private IEnumerable<Foo> CreateFooFromSelect(string sql){
   SQLiteCommand command = new SQLiteCommand(sql, sqlConnection);
   SQLiteDataReader reader = command.ExecuteReader();
   while(reader.Read()){
        yield return new Foo(reader["age"]);
   }
}

在这种情况下,您可以使用AddRange:而不是使用Add

public List<Foo> GetFoos(){
   List<Foo> foos = new List<Foo>();
   string sql = "SELECT * FROM people";
   foos.AddRange(CreateFooFromSelect(sql));
}

您可以在MSDN 上阅读有关yield关键字的更多信息

将CreateFooFromSelect的返回类型更改为IEnumerable<Foo>-yield在返回IEnumerables的方法中用作简写。然后更改foos。添加到foos。AddRange和你应该很好。