Podpora návratové hodnoty odkazu (Visual Basic)

Počínaje jazykem C# 7.0 jazyk C# podporuje referenční návratové hodnoty. Jedním ze způsobem, jak porozumět návratové hodnoty odkazu, je to, že jsou opakem argumentů, které jsou předány odkazem na metodu. Když se změní argument předaný odkazem, změny se projeví v hodnotě proměnné na volajícím. Když metoda poskytne volajícímu návratovou hodnotu odkazu, změny provedené volajícím v návratové hodnotě odkazu se projeví v datech volající metody.

Visual Basic neumožňuje vytvářet metody s návratovou hodnotou odkazu, ale umožňuje využívat referenční návratové hodnoty. Jinými slovy, můžete volat metodu s návratovou hodnotou odkazu a tuto návratovou hodnotu upravit a změny návratové hodnoty odkazu se projeví v datech zvané metody.

Přímé úpravy návratové hodnoty ref

Pro metody, které jsou vždy úspěšné a nemají žádné parametry, můžete ByRef upravit návratovou hodnotu odkazu přímo. To můžete provést přiřazením nové hodnoty k výrazům, které vrací vrácenou hodnotu odkazu.

Následující příklad jazyka C# definuje metodu, která zvýší interní hodnotu a vrátí NumericValue.IncrementValue ji jako návratovou hodnotu odkazu.

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;
   }
}

Vrácená hodnota odkazu je poté upravena volajícím v následujícím Visual Basic příkladu. Všimněte si, že řádek NumericValue.IncrementValue s voláním metody nepřiřaďte metodě hodnotu. Místo toho přiřadí hodnotu návratové hodnotě odkazu vrácené metodou .

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

Použití pomocné metody

V jiných případech nemusí být změna návratové hodnoty odkazu přímého volání metody vždy žádoucí. Například vyhledávací metoda, která vrací řetězec, nemusí vždy najít shodu. V takovém případě chcete upravit vrácenou hodnotu odkazu pouze v případě, že bylo hledání úspěšné.

Tento scénář ilustruje následující příklad jazyka C#. Definuje třídu napsané v jazyce C# zahrnuje metodu , která najde další slovo ve větě, která Sentence FindNext začíná zadaným podřetězecem. Řetězec se vrátí jako návratová hodnota odkazu a proměnná předaná odkazem na metodu určuje, Boolean jestli bylo hledání úspěšné. Návratová hodnota odkazu označuje, že kromě čtení vrácené hodnoty ji volající může také upravit a tato změna se projeví v datech interně obsažených ve Sentence třídě.

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();
    }
}

Přímé úpravy návratové hodnoty odkazu v tomto případě nejsou spolehlivé, protože volání metody nemusí najít shodu a vrátit první slovo ve větě. V takovém případě volající nechtěně změní první slovo věty. To může být znemožněn volajícím, který vrací null (nebo Nothing v Visual Basic). Ale v takovém případě se při pokusu o úpravu řetězce, jehož hodnota je Nothing , vyvolá NullReferenceException . Pokud by volající také mohl vrátit hodnotu , ale to vyžaduje, aby volající definoval řetězcovou proměnnou, String.Empty jejíž hodnota je String.Empty . Přestože volající může tento řetězec upravit, samotná úprava nemá žádný účel, protože upravený řetězec nemá žádný vztah ke slovům ve větě uložené Sentence třídou .

Nejlepším způsobem, jak tento scénář zvládnout, je předat návratovou hodnotu odkazu pomocí odkazu na pomocnou metodu. Pomocná metoda pak obsahuje logiku, která určuje, jestli volání metody proběhlo úspěšně, a pokud ano, k úpravě referenční návratové hodnoty. Následující příklad poskytuje možnou implementaci.

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.

Viz také