Перевод дохода в VB.NET - PullRequest
       14

Перевод дохода в VB.NET

3 голосов
/ 28 сентября 2010

Сначала я должен предположить, что я не очень знаком с ключевым словом C # yield и его функцией.Какой самый лучший / самый простой способ «перевести» его на VB.NET?Особенно я пытался конвертировать этот код в VB.NET, но мне не удалось:

yield return new MatchNode(++index, current.Value);

Что у меня есть:

Imports System.Collections
Imports System.Data.SqlTypes
Imports System.Diagnostics.CodeAnalysis
Imports System.Text.RegularExpressions
Imports Microsoft.SqlServer.Server

Class MatchNode
    Private _index As Integer
    Private _value As String

    Public Sub New(ByVal index As Integer, ByVal value As String)
        _index = index
        _value = value
    End Sub

    Public ReadOnly Property Index() As Integer
        Get
            Return _index
        End Get
    End Property

    Public ReadOnly Property Value() As String
        Get
            Return _value
        End Get
    End Property

End Class

Class MatchIterator
    Implements IEnumerable

    Private _regex As Regex
    Private _input As String

    Public Sub New(ByVal input As String, ByVal pattern As String)
        MyBase.New()
        _regex = New Regex(pattern, UserDefinedFunctions.Options)
        _input = input
    End Sub

    Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        Dim index As Integer = 0
        Dim current As Match = Nothing

        While (current Is Nothing OrElse current.Success)
            If current Is Nothing Then
                current = _regex.Match(_input)
            Else
                current = current.NextMatch()
            End If

            If current.Success Then
                index += 1
                'following should be a VB.Net yield'
                Return New MatchNode(index, current.Value)
            End If

        End While
    End Function
End Class

Partial Public Class UserDefinedFunctions

    <SqlFunction(FillRowMethodName:="FillMatchRow", TableDefinition:="[Index] int,[Text] nvarchar(max)")> _
    Public Shared Function RegexMatches(ByVal input As SqlChars, ByVal pattern As SqlString) As IEnumerable
        Return New MatchIterator(New String(input.Value), pattern.Value)
    End Function

    Public Shared Sub FillMatchRow(ByVal data As Object, ByRef index As SqlInt32, ByRef text As SqlChars)
        Dim node As MatchNode = CType(data, MatchNode)
        index = New SqlInt32(node.Index)
        text = New SqlChars(node.Value.ToCharArray)
    End Sub

End Class

Ответы [ 5 ]

3 голосов
/ 05 мая 2011

Новый Async CTP включает поддержку Yield в VB.NET.

См. Итераторы в Visual Basic для получения информации об использовании.

А теперь включено в .NET 4.5 и VS 2012 .

3 голосов
/ 28 сентября 2010

Вы должны спросить себя, действительно ли я собираюсь редактировать этот код?Если ответ «нет» или «не очень», не беспокойтесь, оставьте его как код C #.

Я разработчик VB.NET и собираюсь отказаться от преобразования кода C # из сети в VB.СЕТЬ.У меня просто есть библиотека C # для необходимого проекта, в который я добавляю код.Только если я обнаружу, что мне нужно регулярно / интенсивно разрабатывать код, я испытываю боль от его преобразования в VB.NET.

3 голосов
/ 28 сентября 2010

Поскольку VB.NET не предоставляет блоки итераторов, вам придется писать класс итераторов вручную, что крайне болезненно. Я постараюсь написать это (вручную) на C # для вас, чтобы вы могли понять, что я имею в виду ... вот так:

internal class MatchIterator : IEnumerable
{
    private class MatchEnumerator : IEnumerator
    {
        int index = 0;
        private Match currentMatch;
        private MatchNode current;
        readonly Regex regex;
        readonly string input;
        public MatchEnumerator(Regex regex, string input)
        {
            this.regex = regex;
            this.input = input;
        }
        public object Current { get { return current; } }

        public void Reset() { throw new NotSupportedException(); }
        public bool MoveNext()
        {
            currentMatch = (currentMatch == null) ? regex.Match(input) : currentMatch.NextMatch();
            if (currentMatch.Success)
            {
                current = new MatchNode(++index, currentMatch.Value);
                return true;
            }
            return false;
        }
    }
    private Regex _regex;
    private string _input;

    public MatchIterator(string input, string pattern)
    {
        _regex = new Regex(pattern, UserDefinedFunctions.Options);
        _input = input;
    }

    public IEnumerator GetEnumerator()
    {
        return new MatchEnumerator(_regex, _input);
    }
}
1 голос
/ 28 сентября 2010

Это замечательная статья Билла МакКарти в журнале Visual Studio об эмуляции yield в VB.NET путем реализации IEnumerable(Of T) и IEnumerator(Of T).

1 голос
/ 28 сентября 2010

Если вы действительно, действительно хотите реализовать класс итератора вручную, я рекомендую сначала прочитать эту главу"C # глубины" Джона Скита, чтобы понять, что c # -компилятор делает с этиммаленькое ключевое слово .

...