我有以下代码:
SqlDataReader reader = getAddressQuery.sqlReader;
while (reader.Read())
{
foreach (Object ob in reader)
{
someText.InnerText = someText.InnerText + " " + ob.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
foreach循环中的代码不会执行.但是,我可以这样做:
SqlDataReader reader = getAddressQuery.sqlReader;
while (reader.Read())
{
someText.InnerText = reader[0].ToString();
}
Run Code Online (Sandbox Code Playgroud)
哪个有效.
显然我可以使用常规for循环而不是foreach循环来实现相同的结果,但我认为foreach语法更清晰,所以我尽可能使用它.
这里出了什么问题?c#中的foreach循环不像更高级语言那样灵活吗?
Joe*_*Joe 24
像下面这样的东西.请注意,IDataReader派生自IDataRecord哪个公开用于处理当前行的成员:
IEnumerable<IDataRecord> GetFromReader(IDataReader reader)
{
while(reader.Read()) yield return reader;
}
foreach(IDataRecord record in GetFromReader(reader))
{
... process it ...
}
Run Code Online (Sandbox Code Playgroud)
或者甚至类似以下内容,从读取器获取枚举或强类型实体对象列表:
IEnumerable<T> GetFromReader<T>(IDataReader reader, Func<IDataRecord, T> processRecord)
{
while(reader.Read()) yield return processRecord(reader);
}
MyType GetMyTypeFromRecord(IDataRecord record)
{
MyType myType = new MyType();
myType.SomeProperty = record[0];
...
return myType;
}
IList<MyType> myResult = GetFromReader(reader, GetMyTypeFromRecord).ToList();
Run Code Online (Sandbox Code Playgroud)
更新以回应Caleb Bell的评论.
我同意Enumerate是一个更好的名字.
事实上,在我个人的"通用"库中,我现在用以下扩展方法替换了上面的内容IDataReader:
public static IEnumerable<IDataRecord> Enumerate(this IDataReader reader)
{
while (reader.Read())
{
yield return reader;
}
}
Run Code Online (Sandbox Code Playgroud)
调用者可以使用以下方法获取强类型对象:
reader.Enumerate.Select(r => GetMyTypeFromRecord(r))
Run Code Online (Sandbox Code Playgroud)
Ada*_*rth 12
该foreach公开的IDataRecord,这使你在一个非常类似的船到while循环:
using (SqlConnection conn = new SqlConnection(""))
using (SqlCommand comm = new SqlCommand("select * from somewhere", conn))
{
conn.Open();
using (var r = comm.ExecuteReader())
{
foreach (DbDataRecord s in r)
{
string val = s.GetString(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想看到更有用的东西,你需要拥有一些自己的代码,将记录中的值提取为更自定义的东西,正如另一个答案所暗示的那样.
无论哪种方式你都需要自定义代码,无论你是否有内联代码或者使用while循环,都取决于我想要编写的频率,不止一次,你应该把它放在一个帮助方法中某处.
并回答一些有问题的问题:问题不在于foreach,它是你试图使用它返回给你的东西,因为你可比较的使用while循环实际上并不具有可比性.
| 归档时间: |
|
| 查看次数: |
38880 次 |
| 最近记录: |