Dela via


Stöd för referensreturvärden (Visual Basic)

C#-språket stöder referensreturvärden. Ett sätt att förstå referensreturvärden är att de är motsatsen till argument som skickas med referens till en metod. När ett argument som skickas av referens ändras återspeglas ändringarna i värdet för variabeln på anroparen. När en metod tillhandahåller ett referensreturvärde till en anropare återspeglas ändringar som görs i referensreturvärdet av anroparen i den anropade metodens data.

Visual Basic tillåter inte att du skapar metoder med referensreturvärden, men du kan använda referensreturvärden. Med andra ord kan du anropa en metod med ett referensreturvärde och ändra det returnerade värdet, och ändringar i referensreturvärdet återspeglas i den anropade metodens data.

Ändra referensreturvärdet direkt

För metoder som alltid lyckas och inte har några ByRef parametrar kan du ändra referensreturvärdet direkt. Det gör du genom att tilldela det nya värdet till de uttryck som returnerar referensreturvärdet.

I följande C#-exempel definieras en NumericValue.IncrementValue metod som ökar ett internt värde och returnerar det som ett referensreturvärde.

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

Referensreturvärdet ändras sedan av anroparen i följande Visual Basic-exempel. Observera att raden med metodanropet NumericValue.IncrementValue inte tilldelar metoden något värde. I stället tilldelar den ett värde till det referensreturvärde som returneras av metoden.

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

Använda en hjälpmetod

I andra fall är det inte alltid önskvärt att ändra referensreturvärdet för ett metodanrop direkt. En sökmetod som returnerar en sträng kanske inte alltid hittar en matchning. I så fall vill du bara ändra referensreturvärdet om sökningen lyckas.

Följande C#-exempel illustrerar det här scenariot. Den definierar en Sentence klass som skrivs i C# innehåller en FindNext metod som hittar nästa ord i en mening som börjar med en angiven delsträng. Strängen returneras som ett referensreturvärde och en Boolean variabel som skickas med referens till metoden anger om sökningen lyckades. Referensreturvärdet anger att anroparen förutom att läsa det returnerade värdet också kan ändra det och att ändringen återspeglas i de data som finns internt i Sentence klassen.

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

Det är inte tillförlitligt att ändra referensreturvärdet direkt i det här fallet, eftersom metodanropet kan misslyckas med att hitta en matchning och returnera det första ordet i meningen. I så fall ändrar anroparen oavsiktligt det första ordet i meningen. Detta kan förhindras av att anroparen returnerar en null (eller Nothing i Visual Basic). Men i så fall försöker du ändra en sträng vars värde Nothing genererar en NullReferenceException. Om kan också förhindras av anroparen som returnerar String.Empty, men detta kräver att anroparen definierar en strängvariabel vars värde är String.Empty. Anroparen kan ändra strängen, men själva ändringen tjänar inget syfte, eftersom den ändrade strängen inte har någon relation till orden i den mening som lagras av Sentence klassen.

Det bästa sättet att hantera det här scenariot är att skicka referensreturvärdet med referens till en hjälpmetod. Hjälpmetoden innehåller sedan logiken för att avgöra om metodanropet lyckades och, om det gjorde det, ändra referensreturvärdet. I följande exempel finns en möjlig implementering.

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.

Se även