while循环中的变量初始化

发布于 2024-10-07 06:22:28 字数 486 浏览 0 评论 0原文

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

public static DataObject ReadNextFile(){ ...}

数据对象看起来像这样:

public DataObject
{
   public string Category { get; set; }

   // And other members ...
}

我想做的是以下基本上

List<DataObject> dataObjects = new List<DataObject>();

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

我知道这可能不是它是如何完成的,因为我如何访问我刚刚读取的对象。

I have a function that reads a file in chunks.

public static DataObject ReadNextFile(){ ...}

And dataobject looks like this:

public DataObject
{
   public string Category { get; set; }

   // And other members ...
}

What I want to do is the following basically

List<DataObject> dataObjects = new List<DataObject>();

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

I know it's probably not how it's done, because how do I access the object I've just read.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只想待在家 2024-10-14 06:22:28

我想你要找的是:

List<DataObject> dataObjects = new List<DataObject>();

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

但我不会那样做。我会写:

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

其中 ReadItems() 是一种返回 IEnumerable 的方法,一次读取并生成一项。您可能很想使用迭代器块(yield return 等)来实现它。

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

(编辑:赛义德此后删除了他对答案的反对意见,但我想我不妨保留这个例子......)

编辑:证明这会起作用,因为赛义德似乎不相信我:

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<DataObject> dataObjects = new List<DataObject>();

        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 个不同对象的引用。

I think what you're looking for is:

List<DataObject> dataObjects = new List<DataObject>();

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

But I wouldn't do that. I'd write:

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

where ReadItems() was a method returning an IEnumerable<DataObject>, reading and yielding one item at a time. You may well want to implement it with an iterator block (yield return etc).

This is assuming you really want to stop reading as soon as you find the first object which has a different category. If you actually want to include all the matching DataObjects,
change TakeWhile to Where in the above LINQ query.

(EDIT: Saeed has since deleted his objections to the answer, but I guess I might as well leave the example up...)

EDIT: Proof that this will work, as Saeed doesn't seem to believe me:

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<DataObject> dataObjects = new List<DataObject>();

        DataObject nextObject;
        while((nextObject = ReadNextFile()).Category == "yes")
        {
            dataObjects.Add(nextObject);
        }

        foreach (DataObject x in dataObjects)
        {
            Console.WriteLine("{0}: {1}", x.Id, x.Category);
        }
    }
}

Output:

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

In other words, the list has retained references to the 5 distinct objects which have been returned from ReadNextFile.

∞觅青森が 2024-10-14 06:22:28

这是主观的,但我讨厌这种模式(并且我充分认识到我是这里的极少数)。当我需要这样的东西时,我是这样做的。

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

但现在,最好说

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

,当然,GetItemsFromFilepath 指向的文件中读取项目并返回 IEnumerable< /代码>。

This is subjective, but I hate this pattern (and I fully recognize that I am in the very small minority here). Here is how I do it when I need something like this.

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

But these days, it is better to say

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

Here, of course, GetItemsFromFile reads the items from the file pointed to by path and returns an IEnumerable<DataObject>.

拍不死你 2024-10-14 06:22:28
List<DataObject> dataObjects = new List<DataObject>();
string category = "";

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

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

List<DataObject> dataObjects = new List<DataObject>();
var category = new DataObject();

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

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

And if you have more complicated object you can do this (like jon):

List<DataObject> dataObjects = new List<DataObject>();
var category = new DataObject();

while((category=ReadNextFile()).Category == "category")
{
   dataObjects.Add(category);
}
零度° 2024-10-14 06:22:28

您应该考虑在类容器上实现 IEnumerator 并调用 ReadNextFile()。然后,您将始终使用 IEnumerator.Current 引用当前对象,并且 MoveNext() 将返回您要查找的布尔值以检查进度。像这样的东西:

public class ObjectReader : IEnumerator<DataObject>
{
    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;
    }
}

You should look into implementing IEnumerator on the class container the call to ReadNextFile(). Then you would always have reference to the current object with IEnumerator.Current, and MoveNext() will return the bool you are looking for to check for advancement. Something like this:

public class ObjectReader : IEnumerator<DataObject>
{
    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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文