2009-07-17 74 views
3

什么是这段代码在VB.NET中的翻译?C#到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; 
    } 
} 

回答

5

这里的问题未进行转换的扩展方法 - 这是转换迭代器块(该方法使用yield return。VB没有任何等同的语言结构 - 你必须创建你自己的实现IEnumerable<T>做过滤,然后从扩展方法返回类的一个实例。

这正是C#编译器有,但它隐藏在幕后

需要注意的一点,其他情况可能并不明显:IEnumerator<T> implements IDisposableforeach循环在最后处理迭代器。这可以是非常重要的 - 所以如果你创建你自己的实现(坦率地说,我建议你不要),你需要调用Disposesource.GetEnumerator()在你自己的Dispose方法返回的迭代器。

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) 
1

问题在于VB不支持迭代器块。你不能只使用VB中现有的Enumerable.Where方法吗?在VB中执行它的另一种懒惰的方式是消耗和过滤整个序列第一个 - 只是返回结果数组/列表,但不会执行C#迭代器块提供的延迟执行。这是一种痛苦;我经常使用具有长(即基本上无限)序列的迭代器块。

6

这个问题很古老,但对于来自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扩展方法必须在其中被自动“共享”或静态模块来定义。

+1

作者George,`Yield`在vb.net 10.0(.Net 4.0)中可用! – toddmo 2015-02-19 01:44:00