2009-03-16 11 views
4

Klingt einfach genug, aber es funktioniert nicht. In diesem Beispiel möchte ich die Werte von 3 Feldern auf 4 setzen. Ich könnte so etwas tun ....Gibt es eine Möglichkeit, mit ParamArray-Werten wie byRef umzugehen, damit sie aktualisiert werden können?

Dim str1 As String = "1" 
Dim str2 As String = "2" 
Dim str3 As String = "3" 
Dim str4 As String = "4" 

str2 = str1 
str3 = str1 
str4 = str1 

... aber das ist eine Art von wortreich (ja, ich weiß, vb ist wortreich in den meisten Fällen). Ich möchte etwas haben, das ich verwenden kann, um dies auf einen einzigen Anruf zu reduzieren, also habe ich diese Erweiterungsmethode gemacht.

Module Module1 

    Sub Main() 

     Dim str1 As String = "1" 
     Dim str2 As String = "2" 
     Dim str3 As String = "3" 
     Dim str4 As String = "4" 

     Console.WriteLine("Extension method return value = {0}", str1.SetEqual(str2, str3, str4)) 
     Console.WriteLine("String 1 = {0}", str1) 
     Console.WriteLine("String 2 = {0}", str2) 
     Console.WriteLine("String 3 = {0}", str3) 
     Console.WriteLine("String 4 = {0}", str4) 

     Console.ReadKey() 

    End Sub 

    <System.Runtime.CompilerServices.Extension()> _ 
    Public Function SetEqual(Of T)(ByVal source As T, _ 
            ByVal ParamArray targets() As T) _ 
            As T 

     For _index = 0 To targets.Length - 1 
      targets(_index) = source 
      Console.WriteLine("Target Value {0} = {1}", _index, targets(_index)) 
     Next 

     Return source 

    End Function 

End Module 

Scheint einfach genug, oder? Nun ist der Ausgang dieser ...

Target Value 0 = 1 
Target Value 1 = 1 
Target Value 2 = 1 
Extension method return value = 1 
String 1 = 1 
String 2 = 2 
String 3 = 3 
String 4 = 4 

Werte in dem param Array nicht in der Rückkehr aktualisiert werden! Ich habe erwartet, dass alle endgültigen Werte jetzt "1" sind, wie sie in der Funktion sind.

Gibt es eine Möglichkeit, eine Update-fähige ParamArray-Sammlung wie diese zu erhalten? ParamArray muss als ByVal deklariert werden, aber mit einem Referenztyp wie String, sollte das nicht nur eine Kopie des Zeigers machen und mir erlauben, den zugrunde liegenden Wert zu ändern?

Gibt es einen besseren Weg, um zu bekommen, was ich will? (C# ist dafür keine Option).

Antwort

5

Was Sie versuchen, kann mit ParamArray nicht erreicht werden. Wenn Sie eine ParamArray Methode aufrufen, tritt das folgende unter der Haube

  1. CLR weist ein Array von geeigneter Länge
  2. Die Werte werden dann in das Array kopiert
  3. Array wird in die Funktion weitergegeben

Es gibt keine Nachaufrufoperation, die die Werte aus dem Array zurück in die ursprünglichen Variablen kopiert, die übergeben wurden.

Die einzige zuverlässige Möglichkeit Damit die Funktion einen Wert ändert und an der Call-Site angezeigt wird, übergeben Sie den Wert ByRef. Du könntest ein bisschen Magie machen, um eine Reihe von Überladungen zu haben, die ByRefs benötigen, die manuell in ein Array konvertiert werden und dann eine Kopie zurück machen. Aber das ist das, was du am nächsten bekommst.

+0

Oh, Freude. Genau davor hatte ich Angst. Danke Jared. – StingyJack

Verwandte Themen