What is the equivalent syntax in VB.NET for “yield return”? [duplicate]

巧了我就是萌 提交于 2019-11-29 11:20:40
Pierre

C#:

yield return scriptRef

VB.NET:

Return New List(Of ScriptReference) From {scriptRef}
Snake

There is none. Period. Unless you are going to write your own state machine, there is no quick fix for this. See the blog post VB.NET's "yield return" .

For those who care about what is actually generated (yes, I love the C# precompiler and compiler :) ):

Try compiling this and take a look at the generated code with .NET Reflector or something:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();

        foreach(var result in foo.Bar())
        {
            Console.WriteLine(result);
        }

        Console.ReadLine();
    }
}

class Foo
{
    public IEnumerable<char> Bar()
    {
        const char start = 'a';

        for(int x = 0;x < 26;x++)
        {
            yield return (char)(start + x);
        }
    }
}

I'm not going to copy the result, it's huge. But do take a look, you'll see that it isn't simple to solve.

There is no exact duplicate of yield in VB. Your best bet would be to create the collection that is being yielded and return it whole for the calling code to iterate over. This isn't quite exactly the same as the code you've given, but it should have the same overall effect. yield is essentially just syntactic sugar for returning parts of a collection to an foreach loop one at a time to optimize run time and allow for early breakout (if you decide you don't need to enumerate over everything after all).

A block of code with yield return/yield break statements is called an iterator. This feature doesn't exist in VB. Of course, it is possible to "translate" that code, but it's not very straightforward... you need to create a custom class implementing IEnumerator(Of Integer) to reproduce exactly the same behavior :

  • Initialize it with the parameters of the original function
  • Implement the "loop" logic in the MoveNext method, by storing the loop variables in private fields. This method should also set a field to hold the current value (n in the original function)
  • Return the current value from the Current property
  • Reset the loop variables in the Reset method
  • Do nothing in the Dispose method

It's doable, but honestly, it's a pain...

Another, easier option would be to fill a List(Of Integer) with the results and return that list : just replace yield return n with list.Add(n)

There isn't. You can however, create one.
Create an iterator class.
A few steps to doing this:

  1. Create a function that is basically a step in the iteration. The function should take whatever arguments each computation needs, and return the arguments for the next computation. (to implement yield break aswell as yield return this function would need to also be able to return some boolean marking the end)
  2. Create a class that implements IEnumerator. The Current property should return the latest computed value, the Reset should reset all the values to their initial ones, and the MoveNext function should compute the next value, and if the computing function returns a false, return a false itself.

For extra credit, make the class generic and capable to work with any function given to it by a delegate.
You can simplify this a bit and make MoveNext be the calculating function itself, but this way it's easy to create different iterators out of the same class implementation.

Oded

There is no equivalent to yield return in VB.NET, but it can be emulated.

See Stack Overflow question Yield in VB.NET and its answers.

Perhaps the Visual Studio Magazine article Use Iterators in VB Now will help.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!