2009-03-16 13 views
4

Semble assez simple, mais il ne fonctionne pas. Dans cet exemple, je veux définir les valeurs de 3 champs pour qu'ils soient égaux à un 4ème. Je pouvais faire quelque chose comme ça ....Existe-t-il un moyen de gérer les valeurs de ParamArray avec byRef afin qu'elles puissent être mises à jour?

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 

... mais c'est un peu verbeux (ouais, je sais, vb est verbeux dans la plupart des cas). Je voudrais avoir quelque chose que je peux utiliser pour réduire cela à un seul appel de ligne, donc j'ai fait cette méthode d'extension.

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 

Semble assez simple, non? Eh bien, la sortie est la suivante ...

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 

Les valeurs dans le tableau de paramètres n'ont pas été mises à jour dans le retour! Je m'attendais à avoir toutes les valeurs finales maintenant "1", comme ils sont dans la fonction.

Est-il possible d'obtenir une collection ParamArray mise à jour de la sorte? ParamArray doit être déclaré ByVal, mais avec un type de référence comme String, ne devrait-il pas seulement faire une copie du pointeur et me permettre de changer la valeur sous-jacente?

Existe-t-il un meilleur moyen d'obtenir ce que je veux? (C# n'est pas une option pour cela).

Répondre

5

Ce que vous essayez de faire ne peut pas être atteint avec ParamArray. Lorsque vous appelez une méthode ParamArray ce qui suit se produit sous le capot

  1. CLR alloue un tableau de longueur appropriée
  2. Les valeurs sont ensuite copiées dans le tableau
  3. tableau est transmis dans la fonction

Il n'y a pas d'opération de post-appel qui copiera les valeurs hors de la matrice et dans les variables d'origine qui ont été transmises.

Le seul moyen fiable avoir la fonction modifier une valeur et l'avoir vu sur le site d'appel est de passer la valeur ByRef. Vous pourriez faire un peu de magie pour avoir un ensemble de surcharges qui prennent ByRefs, convertir manuellement en un tableau et ensuite faire une copie. Mais c'est ce que vous allez obtenir de plus proche.

+0

Oh, Joy. C'est ce dont j'avais peur. Merci Jared. – StingyJack