VB.NET的产量
追随名为yield的关键字。 VB.NET缺少此关键字。 Visual Basic程序员如何解决缺少此关键字的问题?他们实现自己的迭代器类吗?还是他们尝试编写代码来避免需要迭代器?
yield关键字确实会强制编译器在后台进行一些编码。 Cand中迭代器的实现(其结果)(第1部分)就是一个很好的例子。
解决方案
我个人只是编写了自己的继承自IEnumerator(Of T)的迭代器类。确实需要花费一些时间,但我认为最终最好先编写正确的代码,然后再尝试避免使用。我做过的另一种方法是编写一个递归方法,该方法返回IEnumerable(T),仅返回List(Of T),并使用.AddRange。
注意:此答案现在已经很旧了。此后,迭代器块已添加到VB.NET
C在编译时将yield关键字转换为状态机。 VB.NET没有yield关键字,但是它有自己的机制可以安全地将状态嵌入到C#中不易使用的函数中。
通常,使用Shared
关键字将Cstatic
关键字转换为Visual Basic,但是在两个地方会引起混淆。一个问题是Cstatic类实际上是Visual Basic中的Module而不是Shared类(我们可能认为它们可以在Visual Basic中以任何一种方式进行编码,但是没有)。另一个是VB.NET确实有其自己的"静态"关键字。但是,"静态"在VB.NET中具有不同的含义。
我们可以在VB.NET中使用Static
关键字在函数内声明变量,然后在执行函数调用时,变量将保留其状态。这与仅在C#中声明私有静态类成员不同,这是因为VB.NET中的静态函数成员也保证是线程安全的,因为编译器会将其转换为在编译时使用Monitor类。
那么,为什么在这里写下所有这些呢?好吧,应该有可能建立一个可重用的通用Iterator <T>类(或者VB.NET中的Iterator(Of T))。在此类中,我们将使用对应于Ckeywords的Yield()
和Break()
方法来实现C#使用的状态机。然后,我们可以在函数中使用静态实例(就VB.NET而言),以便它最终可以用几乎相同的代码量完成与C#的" yield"几乎相同的工作(丢弃类实现本身,因为它将可以无限重复使用)。
我还不太关心Yield自己尝试做的事情,但这应该是可行的。就是说,这也不是一件容易的事,因为Cteam成员Eric Lippert称之为"编译器中最复杂的转换"。
自从一年多以前编写此草稿以来,我也开始相信,直到Visual Studio 2010发行出来之前,以一种有意义的方式实际上是不可能的,因为它将需要向Iterator类发送多个lambda,因此实际上实际上,我们需要.NET 4对多行lambda的支持。
希望这将成为即将发布的VB版本的历史。由于迭代器实际上在新范式(尤其是LINQ与惰性评估结合)中变得越来越重要,据我从Paul Vick的博客了解,这具有很高的优先级。再说一次,Paul不再是VB团队的负责人,而且我还没有时间观看PCD的谈话。
不过,如果我们有兴趣,可以将它们链接到Paul的博客中。
Visual Studio Magazine中的Bill McCarthy发表了一篇不错的文章,即在VB中使用Iterators,它在VB.NET中模拟了" yield"。或者,等待下一个版本的Visual Basic。