【问题标题】:Can I implement yield return for IEnumerable functions in VB.NET? [duplicate]我可以在 VB.NET 中为 IEnumerable 函数实现收益返回吗? [复制]
【发布时间】:2010-10-26 21:51:42
【问题描述】:

可能重复:
Yield In VB.NET

在 C# 中,当编写返回 IEnumerble<> 的函数时,您可以使用 yield return 来返回枚举的单个项目,并使用 yield break; 表示没有剩余项目。做同样事情的 VB.NET 语法是什么?

来自NerdDinner 代码的示例:

public IEnumerable<RuleViolation> GetRuleViolations() {

   if (String.IsNullOrEmpty(Title))
       yield return new RuleViolation("Title required","Title");

   if (String.IsNullOrEmpty(Description))
       yield return new RuleViolation("Description required","Description");

   if (String.IsNullOrEmpty(HostedBy))
       yield return new RuleViolation("HostedBy required", "HostedBy");

   if (String.IsNullOrEmpty(Address))
       yield return new RuleViolation("Address required", "Address");

   if (String.IsNullOrEmpty(Country))
       yield return new RuleViolation("Country required", "Country");

   if (String.IsNullOrEmpty(ContactPhone))
       yield return new RuleViolation("Phone# required", "ContactPhone");

   if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
       yield return new RuleViolation("Phone# does not match country", "ContactPhone");

   yield break;
}

convert C# to VB.NET tool 给出“YieldStatement 不受支持”错误。

【问题讨论】:

  • 请注意,让步并不是回归,至少在大多数人的意思上不是回归(尽管它是在幕后实现的方式)。此外,您不需要在那里的收益中断。此外,您可能需要考虑将该代码从生成 RuleViolation 对象的枚举转换为生成 Func 委托的枚举。
  • 使用yield让我想起了管道,因为调用代码可以在返回ienumerable的函数完成运行之前开始迭代ienumerable。很酷!
  • 这是一个糟糕的例子,因为你公然不需要 yeild 来处理这样的事情:懒惰地确定违反规则有什么好处?把它们都塞进一个列表中,然后就可以完成了。这并不是说 yeild 没有用,但这只是一个不好的例子
  • @piers7,自从我发布这个问题以来,我学到了很多关于产量和迭代器的知识,我不得不同意你的看法。这只是我第一次看到产量,所以这就是我包含这个例子的原因。迄今为止我见过的最好的例子是一个没有预设大小限制的素数生成器(当然 MaxInt 除外)
  • 对于 piers7,我不确定这是不是一个糟糕的例子。它根据需要评估条件,并在任何消耗它停止时停止。

标签: vb.net ienumerable iterator yield-return


【解决方案1】:

新的Async CTP 包括在VB.NET 中对Yield 的支持。

有关使用信息,请参阅Iterators in Visual Basic

【讨论】:

    【解决方案2】:

    下面给出输出:2、4、8、16、32

    在 VB 中,

    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;
            //List<int> results = new List<int>();
            int result=1;
            while (counter < 5)
            {
              result = result * 2;
              counter += 1;
              yield return result;
            }
        }
    

    【讨论】:

    • 是的,对于这个简单的例子,它会起作用。还有其他更好的迭代器示例,您不想或不能在单个函数调用中创建整个列表。您的 C# 代码仅在您在 foreach 循环中使用它们时计算每个值。当您调用setOfNumbers 函数时,VB 代码会计算所有值。这是一个显着的差异。
    【解决方案3】:

    在幕后,编译器创建一个枚举器类来完成这项工作。由于 VB.NET 没有实现这种模式,你必须创建自己的 IEnumerator(Of T) 实现

    【讨论】:

      【解决方案4】:

      在这里查看我的答案:

      总结一下:
      VB.Net 没有 yield,但 C# 通过将代码转换为幕后的状态机来实现 yield。 VB.Net 的Static 关键字还允许您在函数中存储状态,因此理论上您应该能够实现一个类,当用作方法的Static 成员时,您可以编写类似的代码。

      【讨论】:

        【解决方案5】:

        目前在语言语法级别上,VB.Net 中没有等效于 C# 的 yield return。

        但是,Bill McCarthy 最近在 MSDN 杂志上发表了一篇关于如何在 VB.Net 9.0 中实现类似模式的文章

        【讨论】:

          【解决方案6】:

          在 VB.NET 中没有收益回报 :( 只需创建一个列表并返回它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-27
            • 2013-05-31
            • 2010-09-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多