【问题标题】:C# to VB .NET yield return conversionC# 到 VB .NET 产生返回转换
【发布时间】:2023-03-19 15:55:01
【问题描述】:

这个 sn-p 在 VB .NET 中的翻译是什么?

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, Boolean> predicate)
{
  foreach (TSource element in source)
  {
    if (predicate(element))
    yield return element;
  }
} 

【问题讨论】:

    标签: c# .net vb.net


    【解决方案1】:

    这个问题很老了,但是对于从 Google 来到这里的人来说,这是个好消息 - VB.NET 的新版本支持 c# yield return 运算符(我相信这是 VS.NET 2010/2012 w/.net 4.0 )...这是转换后的示例:

    <System.Runtime.CompilerServices.Extension> _
    Public Iterator Function Where(Of TSource)(source As IEnumerable(Of TSource), predicate As Func(Of TSource, [Boolean])) As IEnumerable(Of TSource)
        '' non-lambda version of the method body
        'For Each element As TSource In source
        '    If predicate(element) Then
        '        Yield element
        '    End If 
        'Next
        For Each element As TSource In From item In source Where predicate(item)
            Yield element
        Next
    End Function
    

    无需将静态更改为共享,因为必须在自动“共享”或静态的模块中定义 VB.NET 扩展方法。

    【讨论】:

      【解决方案2】:

      不幸的是,据我所知,VB.net 没有对应的 yield 关键字。为了实现yield 功能,您必须考虑使用IEnumerable&lt;T&gt; 做一些花哨的动作......您可以查看this article 以获得良好的演练。

      如果您只是在寻找扩展方法的语法,它应该是这样的:

      <System.Runtime.CompilerServices.Extension> _
      Public Shared Function Where(Of TSource) ( _
                      ByVal source As IEnumerable(Of TSource), _
                      ByVal predicate As Func(Of TSource, [Boolean])) _
             As IEnumerable(Of TSource)
      

      【讨论】:

        【解决方案3】:

        问题在于 VB 不支持迭代器块。你不能只使用VB中现有的Enumerable.Where方法吗?

        在 VB 中执行此操作的另一种懒惰方式是消耗和过滤整个序列 first - 并且只返回结果数组/列表,但这不会像 C# 那样延迟执行迭代器块提供。这是一种痛苦;我经常使用具有长(即基本上无限)序列的迭代器块。

        【讨论】:

          【解决方案4】:

          这里的问题不是转换扩展方法 - 它是转换迭代器块(该方法使用 yield return。VB 没有任何等效的语言结构 - 您必须创建自己的 IEnumerable&lt;T&gt; 实现过滤,然后从扩展方法返回一个类的实例。

          这正是 C# 编译器所做的,但它隐藏在幕后。

          有一点需要注意,否则可能不明显:IEnumerator&lt;T&gt; 实现了IDisposableforeach 循环在最后处理了迭代器。这可能非常重要 - 因此,如果您确实创建了自己的实现(坦率地说,我建议您不要这样做),您需要在返回的迭代器上调用 Dispose来自source.GetEnumerator() 在你自己的Dispose 方法中。

          【讨论】:

            猜你喜欢
            • 2017-09-02
            • 2013-11-29
            • 2014-12-24
            • 2017-08-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多