在VB.NET中产量

C#有关键字叫yield 。 VB.NET缺less这个关键字。 Visual Basic程序员如何解决缺less这个关键字的问题? 他们是否实现了自己的迭代器类? 还是他们尝试编码,以避免迭代器的需要?

yield关键字确实会迫使编译器在幕后执行一些编码。 C#中迭代器的实现及其后果(第一部分)就是一个很好的例子。

注意:这个答案现在已经老了。 Iterator块已经被添加到VB.NET中

C#在编译时将yield关键字转换成状态机。 VB.NET没有yield关键字,但是它确实有自己的机制来安全地将状态embedded到C#中不容易获得的函数中。

C# static关键字通常使用Shared关键字转换为Visual Basic,但有两个地方令人困惑。 一个是,C#静态类实际上是Visual Basic中的一个模块,而不是一个Shared类(你会认为他们会让你在Visual Basic中编写代码,但是不会)。 另一个是VB.NET有它自己的Static关键字。 但是, Static在VB.NET中有不同的含义。

你在VB.NET中使用Static关键字来声明一个函数内部的variables,当你做这个variables时,函数调用会保留它的状态。 这与在C#中声明私有静态类成员不同,因为VB.NET中的静态函数成员保证也是线程安全的,因为编译器会在编译时将其转换为使用Monitor类。

那么为什么把这些写在这里? 那么,应该可以在VB.NET中构build一个可重用的genericsIterator<T>类(或Iterator(Of T) )。 在这个类中,您将实现C#使用的状态机,并使用与C#关键字对应的Yield()Break()方法。 然后你可以在一个函数中使用一个静态实例(在VB.NET的意义上),这样它就可以在大致相同的代码量下完成与C#的yield相同的工作(抛弃class实现本身,因为它会是无限可重用)。

我对收益率没有足够的关注,只能自己尝试,但应该可行。 尽pipe如此,C#团队成员Eric Lippert称这是“ 编译器中最复杂的转换 ”,这也远非微不足道。 自从我写了一年前的第一份草稿以来,我也相信,直到Visual Studio 2010发布之前,这并不是真的有意义,因为它需要向Iterator类发送多个lambdaexpression式,所以才能真正实现实际上我们需要[.NET 4 3支持多行lambdaexpression式。

asynchronousCTP在VB.NET中包含对Yield支持。

有关使用情况的信息,请参阅Visual Basic中的迭代器 。

现在它被包含在Visual Studio 2012的包装盒中!

有很好的文章使用 Visual Studio杂志中的Bill McCarthy 在VB中使用迭代器来模拟VB.NET的yield 。 或者等待下一个版本的Visual Basic。

我个人只是写我自己的inheritance自IEnumerator(Of T)的迭代器类。 确实需要一段时间才能把它做好,但是我认为最好写好,然后尽量避免。 我所做的另一个方法是编写一个recursion方法,返回IEnumerable(Of T),并返回List(Of T)并使用.AddRange。

希望这将是即将到来的VB版本的事情。 由于迭代器对于新的范式(尤其是LINQ与懒惰评估相结合)实际上变得非常重要,就我所知,Paul Vick的博客中,这个优先级相当高。 再一次,保罗不再是VB团队的负责人,我还没有时间去观看PCD会谈。

不过,如果你有兴趣,他们在保罗的博客链接。

下面的代码给出了输出

2,4,8,16,32

在VB.NET中,

 Public Shared Function setofNumbers() As Integer() Dim counter As Integer = 0 Dim results As New List(Of Integer) Dim result As Integer = 1 While counter < 5 result = result * 2 results.Add(result) counter += 1 End While Return results.ToArray() End Function Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load For Each i As Integer In setofNumbers() MessageBox.Show(i) Next End Sub 

在C#

 private void Form1_Load(object sender, EventArgs e) { foreach (int i in setofNumbers()) { MessageBox.Show(i.ToString()); } } public static IEnumerable<int> setofNumbers() { int counter=0; int result=1; while (counter < 5) { result = result * 2; counter += 1; yield return result; } }