C#到VB .NET产生返回转换

时间:2009-07-17 19:29:49

标签: c# .net vb.net

这个片段在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 个答案:

答案 0 :(得分:5)

这里的问题不是转换扩展方法 - 它正在转换迭代器块(该方法使用yield return。VB没有任何等效的语言构造 - 你必须创建自己的{ {1}}进行了过滤,然后从扩展方法返回该类的实例。

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

有一点需要注意,否则可能并不明显:IEnumerable<T>实现IEnumerator<T>,并且IDisposable循环在最后处置迭代器。这可能非常重要 - 所以,如果您创建自己的实现(我建议您不要,坦率地说),您需要调用foreach迭代器从您Dispose方法中的source.GetEnumerator()返回。

答案 1 :(得分:5)

这个问题已经过时了,但对于来自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 :(得分:3)

不幸的是,据我所知,VB.net没有等同于yield的关键字。为了实现yield功能,您必须考虑使用IEnumerable<T>进行一些奇特的移动...您可以查看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 :(得分:1)

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

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