Podpora návratových hodnot odkazů (Visual Basic)
Jazyk C# podporuje návratové hodnoty odkazů. Jedním ze způsobů, jak porozumět návratovým hodnotám odkazu, je, že jsou opakem argumentů, které jsou předány odkazem na metodu. Při změně argumentu předaného odkazem se změny projeví v hodnotě proměnné volajícího. Pokud metoda poskytuje volajícímu návratovou hodnotu odkazu, změny návratové hodnoty odkazu volajícím se projeví v datech volané metody.
Jazyk Visual Basic neumožňuje vytvářet metody s návratovými hodnotami odkazu, ale umožňuje využívat návratové hodnoty odkazu. Jinými slovy, můžete volat metodu s návratovou hodnotou odkazu a upravit tuto návratovou hodnotu a změny návratové hodnoty odkazu se projeví v datech volané metody.
Úprava návratové hodnoty odkazu přímo
U metod, které jsou vždy úspěšné a nemají žádné ByRef
parametry, můžete upravit návratové hodnoty odkazu přímo. Uděláte to tak, že přiřadíte novou hodnotu výrazům, které vrátí návratové hodnoty odkazu.
Následující příklad jazyka C# definuje metodu NumericValue.IncrementValue
, která zvýší vnitřní hodnotu a vrátí 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;
}
}
Návratová hodnota odkazu je pak změněna volajícím v následujícím příkladu jazyka Visual Basic. Všimněte si, že řádek volání NumericValue.IncrementValue
metody nepřiřazuje hodnotu metodě. Místo toho přiřadí hodnotu k návratové hodnotě odkazu vrácenou 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 úprava návratové hodnoty odkazu 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 návratové hodnoty odkazu pouze v případě, že hledání proběhlo úspěšně.
Tento scénář ilustruje následující příklad jazyka C#. Definuje třídu napsanou Sentence
v jazyce C# obsahuje metodu FindNext
, která najde další slovo ve větě, která začíná zadaným podřetězí. Řetězec se vrátí jako návratová hodnota odkazu a Boolean
proměnná předaná odkazem na metodu označuje, zda bylo hledání úspěšné. Návratová hodnota odkazu označuje, že kromě čtení vrácené hodnoty může volající také upravit a tato změna se projeví v datech obsažených interně 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á úprava návratové hodnoty odkazu v tomto případě není 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í neúmyslně upraví první slovo věty. Volajícímu, který vrací null
(nebo Nothing
v jazyce Visual Basic), to může zabránit. V takovém případě se ale pokusíte upravit řetězec, jehož hodnota je Nothing
vyvolán NullReferenceException. Pokud by volající mohl také zabránit vrácení String.Empty, ale to vyžaduje, aby volající definoval řetězcovou proměnnou, jejíž hodnota je String.Empty. Volající sice může tento řetězec upravit, ale samotná změna neslouží k žádnému účelu, protože upravený řetězec nemá žádný vztah ke slovům ve větě uložené ve Sentence
třídě.
Nejlepším způsobem, jak tento scénář zpracovat, je předat návratovou hodnotu odkazu odkazem na pomocnou metodu. Pomocná metoda pak obsahuje logiku, která určuje, zda volání metody bylo úspěšné a pokud ano, upravit návratové hodnoty odkazu. 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.