将C#的yield return转换为VB .NET

3
这段代码在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;
  }
} 
4个回答

5
这里的问题不在于转换扩展方法,而是转换迭代器块(该方法使用yield return)。VB没有任何等效的语言结构,你需要创建自己的IEnumerable<T>实现来进行过滤,然后从扩展方法返回该类的实例。
这正是C#编译器所做的,但它被隐藏在幕后。
需要注意的一点是:IEnumerator<T>实现了IDisposable,而foreach循环在结束时会处理迭代器。这可能非常重要-因此,如果您确实创建了自己的实现(老实说我建议您不要这样做),则需要在自己的Dispose方法中调用source.GetEnumerator()返回的迭代器上的Dispose方法。

5

这个问题虽然有些陈旧,但对于从谷歌搜索到此处的人来说,有一个好消息——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扩展方法必须在模块中定义,这些模块自动是“共享”或静态的。

3
很遗憾,就我所知,VB.net没有与yield关键字相对应的等效物。为了实现yield功能,你需要使用IEnumerable<T>进行一些高级操作...你可以查看这篇文章以获取详细步骤。
如果你只是想要扩展方法的语法,那么以下是示例代码:
<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)

1

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

在VB中实现的另一种“懒惰”的方法是首先消耗和过滤整个序列 - 然后仅返回结果数组/列表,但这没有C#迭代器块提供的延迟执行。 这很麻烦;我经常在长(即基本上无限)序列中使用迭代器块。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接