简体   繁体   English

什么时候自定义枚举/集合有用?

[英]When is custom enumerable/collection useful?

I am dropping this line after having visited different websites to try understand real time example of using custom enumeration. 我访问了不同的网站,试图了解使用自定义枚举的实时示例,我正在放弃这一行。 I got examples. 我有例子。 But they lead me to confusion. 但他们让我感到困惑。

Example

Take 1 拿1

class NumberArray
{
    public int[] scores;

    public NumberArray()
    {
    }

    public NumberArray(int[] scores)
    {
        this.scores = scores;
    }

    public int[] Scores
    {
        get {return scores;}
    }

}

Take 2 拿2

public class Enumerator : IEnumerator
{
    int[] scores;
    int cur;
    public Enumerator(int[] scores)
    {
        this.scores = scores;
        cur = -1;
    }
    public Object Current
    {
        get {
            return scores[cur];
        }
    }

    public void Reset()
    {
        cur = -1;
    }

    public bool MoveNext()
    {
        cur++;
        if (cur < scores.Length)
            return true;
        else return false;
    }
}

public class Enumerable : IEnumerable
{
    int[] numbers;

    public void GetNumbersForEnumeration(int[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(numbers);
    }
}

Main 主要

static void Main()
{
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    NumberArray num = new NumberArray(arr);
    foreach(int val in num.Scores)
    {
        Console.WriteLine(val);
    }

    Enumerable en = new Enumerable();
    en.GetNumbersForEnumeration(arr);

    foreach (int i in en)
    {
        Console.WriteLine(i);
    }
    Console.ReadKey(true);
}

In take 2, I followed the custom iteration to iterate the same integer array as I did in take 1. Why should I beat about the bush to iterate an integer by using custom iteration ? 在第2部分中,我按照自定义迭代迭代相同的整数数组,就像我在第1步中所做的那样。为什么我应该通过使用自定义迭代来尝试迭代整数

Probably I missed out the real-time custom iteration need. 可能我错过了实时自定义迭代需求。 Can you explain me the task which I can't do with existing iteration facility? 你能解释一下我不能用现有的迭代工具做的任务吗? ( I just finished my schooling, so give me a simple example, so that I can understand it properly ). 我刚完成学业,所以给我一个简单的例子,这样我就能理解它 )。

Update : I took those examples from some site. 更新: 我从某个网站上获取了这些示例。 There is nothing special in that code, we can achieve it very simply even without using custom iteration, my interest was to know the real scenario where custom iteration is quite handy. 该代码没有什么特别之处,即使不使用自定义迭代,我们也可以非常简单地实现它,我的兴趣是了解自定义迭代非常方便的真实场景。

Custom iterators are useful when the resources you are iterating are not pre-loaded in memory, but rather obtained as needed in each iteration. 当您迭代的资源没有预先加载到内存中,而是在每次迭代中根据需要获取时,自定义迭代器非常有用。 For example, in LINQ to SQL, when you do something like: 例如,在LINQ to SQL中,当您执行以下操作时:

foreach(var employee in dataContext.Employees) {
    // Process employee
}

in each step of the foreach loop, the Employees table in the database is queried to get the next record. foreach循环的每个步骤中,查询数据库中的Employees表以获取下一条记录。 This way, if you exit the loop early, you haven't read the whole table, but only the records you needed. 这样,如果您提前退出循环,则不会读取整个表,而只会读取所需的记录。

See here for a real-world example: enumerate lines on a file . 请参阅此处获取实际示例: 枚举文件中的行 Here, each line is read from the file on each iteration of the foreach loop. 这里,在foreach循环的每次迭代中从文件中读取每一行。 (as a side note, .NET Framework 4 offers this same functionality built-in). (作为旁注,.NET Framework 4提供了内置的相同功能)。

To be honest, I am not entirely sure what you're asking, but if you're concerned about the difference between returning an array (as in take 1) and returning an iterator (take 2), here is my answer. 说实话,我并不完全确定你在问什么,但如果你担心返回一个数组(如第1段)和返回迭代器(第2步)之间的区别,这是我的答案。

There a big difference between returning an array and returning an iterator. 返回数组和返回迭代器之间有很大的不同。 Returning an array means returning internal state (unless you make a copy as part of the return, but that is expensive). 返回数组意味着返回内部状态(除非您将副本作为返回的一部分进行,但这很昂贵)。 If you return an iterator, you just return an abstraction, that will let callers iterate state. 如果返回迭代器,则只返回一个抽象,这将使调用者迭代状态。 This also means, that you can do lazy evaluation if you need to (something you obviously can't do if you're returning an array). 这也意味着,如果需要,你可以进行延迟评估(如果你返回一个数组,你显然不能做的事情)。

Also, with the support for iterators in C# 2, there is really no reason to implement IEnumerable by hand. 此外,由于C#2中对迭代器的支持,实际上没有理由手动实现IEnumerable。 Please see this question for additional detail Can someone demystify the yield keyword? 有关其他详细信息,请参阅此问题。 有人可以揭开yield关键字的神秘面纱吗?

Just as another example where custom iteration has been useful to me in the past was to provide a common abstraction to recursively enumerate all nodes in a tree structure... 正如另一个自定义迭代在过去对我有用的例子是提供一个通用的抽象来递归地枚举树结构中的所有节点......

foreach (Node n in tree)
  //...do something

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM