Obsługa wartości zwracanych odwołań (Visual Basic)

Język C# obsługuje zwracane wartości odwołania. Jednym ze sposobów zrozumienia wartości zwracanych odwołań jest to, że są one przeciwieństwem argumentów przekazywanych przez odwołanie do metody. Po zmodyfikowaniu argumentu przekazanego przez odwołanie zmiany są odzwierciedlane w wartości zmiennej obiektu wywołującego. Gdy metoda dostarcza wartość zwracaną odwołania do obiektu wywołującego, modyfikacje wprowadzone w wartości zwracanej przez obiekt wywołujący są odzwierciedlane w danych wywoływanej metody.

Visual Basic nie zezwala na tworzenie metod z wartościami zwracanymi odwołaniami, ale umożliwia korzystanie z wartości zwracanych odwołań. Innymi słowy, można wywołać metodę z wartością zwracaną odwołania i zmodyfikować tę wartość zwracaną, a zmiany w wartości zwracanej odwołania są odzwierciedlane w danych wywoływanej metody.

Bezpośrednie modyfikowanie wartości zwracanej ref

W przypadku metod, które zawsze kończą się powodzeniem i nie ByRef mają parametrów, można bezpośrednio zmodyfikować wartość zwracaną przez odwołanie. W tym celu należy przypisać nową wartość do wyrażeń, które zwracają wartość zwracaną przez odwołanie.

Poniższy przykład w języku C# definiuje metodę NumericValue.IncrementValue , która zwiększa wartość wewnętrzną i zwraca ją jako wartość zwracaną przez odwołanie.

using System;

public class NumericValue
{
   private int value = 0;

   public NumericValue(int value)
   {
      this.value = value;
   }

   public ref int IncrementValue()
   {
      value++;
      return ref value;
   }

   public int GetValue()
   {
      return value;
   }
}

Wartość zwracana odwołania jest następnie modyfikowana przez obiekt wywołujący w poniższym przykładzie języka Visual Basic. Należy pamiętać, że wiersz z NumericValue.IncrementValue wywołaniem metody nie przypisuje wartości do metody . Zamiast tego przypisuje wartość do zwracanej wartości odwołania zwróconej przez metodę .

Module Example
   Public Sub Main()
      Dim n As New NumericValue(15)
      n.IncrementValue() += 12
      Console.WriteLine(n.GetValue) 
   End Sub
End Module
' Output:   28

Używanie metody pomocniczej

W innych przypadkach modyfikowanie wartości zwracanej odwołania wywołania metody bezpośrednio może nie zawsze być pożądane. Na przykład metoda wyszukiwania zwracająca ciąg może nie zawsze znajdować dopasowanie. W takim przypadku chcesz zmodyfikować wartość zwracaną odwołania tylko wtedy, gdy wyszukiwanie zakończy się pomyślnie.

Poniższy przykład w języku C# ilustruje ten scenariusz. Definiuje klasę napisaną Sentence w języku C# zawiera metodę FindNext , która znajduje następne słowo w zdaniu rozpoczynającym się od określonego podciągnięcia. Ciąg jest zwracany jako wartość zwracana przez odwołanie, a Boolean zmienna przekazana przez odwołanie do metody wskazuje, czy wyszukiwanie zakończyło się pomyślnie. Wartość zwracana odwołania wskazuje, że oprócz odczytywania zwróconej wartości obiekt wywołujący może go również modyfikować i że modyfikacja jest odzwierciedlana w danych zawartych wewnętrznie w Sentence klasie.

using System;

public class Sentence
{
    private string[] words;
    private int currentSearchPointer;

    public Sentence(string sentence)
    {
        words = sentence.Split(' ');
        currentSearchPointer = -1;
    }

    public ref string FindNext(string startWithString, ref bool found)
    {
        for (int count = currentSearchPointer + 1; count < words.Length; count++)
        {
            if (words[count].StartsWith(startWithString))
            {
                currentSearchPointer = count;
                found = true;
                return ref words[currentSearchPointer];
            }
        }
        currentSearchPointer = -1;
        found = false;
        return ref words[0];
    }

    public string GetSentence()
    {
        string stringToReturn = null;
        foreach (var word in words)
            stringToReturn += $"{word} ";

        return stringToReturn.Trim();
    }
}

Bezpośrednie modyfikowanie wartości zwracanej odwołania w tym przypadku nie jest wiarygodne, ponieważ wywołanie metody może nie odnaleźć dopasowania i zwrócić pierwsze słowo w zdaniu. W takim przypadku obiekt wywołujący przypadkowo zmodyfikuje pierwsze słowo zdania. Może to być uniemożliwione przez obiekt wywołujący zwraca element null (lub Nothing w Visual Basic). Jednak w takim przypadku próba zmodyfikowania ciągu, którego wartość jest Nothing zgłaszana jako NullReferenceException. Jeśli można również zapobiec zwracaniu String.Emptyprzez obiekt wywołujący , ale wymaga to, aby obiekt wywołujący zdefiniował zmienną ciągu, której wartością jest String.Empty. Chociaż obiekt wywołujący może zmodyfikować ten ciąg, sama modyfikacja nie służy żadnemu celowi, ponieważ zmodyfikowany ciąg nie ma relacji ze słowami w zdaniu przechowywanym przez klasę Sentence .

Najlepszym sposobem obsługi tego scenariusza jest przekazanie wartości zwracanej odwołania przez odwołanie do metody pomocniczej. Metoda pomocnika zawiera następnie logikę, aby określić, czy wywołanie metody powiodło się i, jeśli tak, aby zmodyfikować wartość zwracaną odwołania. W poniższym przykładzie przedstawiono możliwą implementację.

Module Example
   Public Sub Main()
      Dim sentence As New Sentence("A time to see the world is now.")
      Dim found = False
      Dim returns = RefHelper(sentence.FindNext("A", found), "A good", found) 
      Console.WriteLine(sentence.GetSentence()) 
   End Sub
   
   Private Function RefHelper(ByRef stringFound As String, replacement As String, success As Boolean) _ 
                    As (originalString As String, found As Boolean) 
      Dim originalString = stringFound
      If found Then stringFound = replacement
      Return (originalString, found)   
   End Function
End Module
' The example displays the following output:
'      A good time to see the world is now.

Zobacz też