这个片段在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;
}
}
答案 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#的延迟执行迭代器块提供。这是一种痛苦;我经常使用具有长(即基本无限)序列的迭代器块。