while循环中的可变初始化

我有一个以块的forms读取文件的函数。

public static DataObject ReadNextFile(){ ...} 

而dataobject看起来像这样:

 public DataObject { public string Category { get; set; } // And other members ... } 

基本上我想做的是以下内容

 List dataObjects = new List(); while(ReadNextFile().Category == "category") { dataObjects.Add(^^^^^ the thingy in the while); } 

我知道它可能不是这样做的,因为我如何访问我刚读过的对象。

我想你要找的是:

 List dataObjects = new List(); DataObject nextObject; while((nextObject = ReadNextFile()).Category == "category") { dataObjects.Add(nextObject); } 

但我不会这样做。 我写道:

 List dataObject = source.ReadItems() .TakeWhile(x => x.Category == "Category") .ToList(); 

其中ReadItems()是一个返回IEnumerable ,一次读取并生成一个项目。 您可能希望使用迭代器块( yield return等)来实现它。

这假设您确实希望在找到具有不同类别的第一个对象后立即停止阅读。 如果您确实想要包含所有匹配的DataObjectTakeWhile更改为上述LINQ查询中的Where

(编辑:Saeed已经删除了他对答案的反对意见,但我想我不妨留下这个例子……)

编辑:certificate这将有效,因为赛义德似乎不相信我:

 using System; using System.Collections.Generic; public class DataObject { public string Category { get; set; } public int Id { get; set; } } class Test { static int count = 0; static DataObject ReadNextFile() { count++; return new DataObject { Category = count <= 5 ? "yes" : "no", Id = count }; } static void Main() { List dataObjects = new List(); DataObject nextObject; while((nextObject = ReadNextFile()).Category == "yes") { dataObjects.Add(nextObject); } foreach (DataObject x in dataObjects) { Console.WriteLine("{0}: {1}", x.Id, x.Category); } } } 

输出:

 1: yes 2: yes 3: yes 4: yes 5: yes 

换句话说,该列表保留了对从ReadNextFile返回的5个不同对象的ReadNextFile

 List dataObjects = new List(); string category = ""; while((category=ReadNextFile().Category) == "category") { dataObjects.Add(new DataObject{Category = category}); } 

如果你有更复杂的对象,你可以这样做(如jon):

 List dataObjects = new List(); var category = new DataObject(); while((category=ReadNextFile()).Category == "category") { dataObjects.Add(category); } 

这是主观的,但我讨厌这种模式(我完全认识到我在这里的人数很少)。 当我需要这样的东西时,我就是这样做的。

 var dataObjects = new List(); while(true) { DataObject obj = ReadNextFile(); if(obj.Category != "category") { break; } dataObjects.Add(obj); } 

但是现在,最好说

 List dataObjects = GetItemsFromFile(path) .TakeWhile(x => x.Category == "category") .ToList(); 

当然,这里GetItemsFromFilepath指向的文件中读取项目并返回IEnumerable

您应该考虑在类容器上实现IEnumerator对ReadNextFile()的调用。 然后你总是会用IEnumerator.Current引用当前对象,而MoveNext()将返回你想要检查进度的bool。 像这样的东西:

 public class ObjectReader : IEnumerator { public bool MoveNext() { // try to read next file, return false if you can't // if you can, set the Current to the returned DataObject } public DataObject Current { get; private set; } }