有没有办法将ParamArray值作为byRef处理,以便可以更新?

时间:2009-03-16 12:34:16

标签: vb.net parameters byref paramarray

听起来很简单,但它不起作用。在这个例子中,我想将3个字段的值设置为等于4。我可以这样做......

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

......但那有点罗嗦(是的,我知道,在大多数情况下,vb是罗嗦的)。我想有一些东西可以用来将它减少到一个单行调用,所以我做了这个扩展方法。

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

看起来很简单,对吧?那么,输出就是这个......

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

param数组中的值未在返回时更新!我期待所有的最终值现在都是“1”,就像它们在函数中一样。

有没有办法获得像这样的可更新的ParamArray集合? ParamArray必须声明为ByVal,但是使用像String这样的引用类型,不应只制作指针的副本并允许我更改基础值吗?

有没有更好的方法来获得我想要的东西? (C#不是一个选项)。

2 个答案:

答案 0 :(得分:5)

使用ParamArray无法实现您想要做的事情。当您调用ParamArray方法时,会发生以下情况

  1. CLR分配一个适当长度的数组
  2. 然后将值复制到数组
  3. 将数组传递给函数
  4. 没有调用后操作会将值从数组中复制回传入的原始变量中。

    让函数修改一个值并让它在调用站点看到的唯一可靠方法是传递值ByRef。你可以做一些魔术来获得一组过载,这些过载采用ByRefs,手动转换为数组,然后进行复制。但那是你最接近的。

答案 1 :(得分:0)

在适当情况下(大约10年前)可能会有点迟,但是如果可行,可能会帮助其他人...

您不能将参数数组作为引用,但是可以将数组作为引用。

将其更改为 ByRef ,然后删除 ParamArray

然后修改此行:

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

只需注意附加的“ {”和“}”即可将字符串作为数组而不是ParamArray传递

我在一个类中使用了它来传递控件数组,并且它可以工作(ParamArray不能使用),所以我希望(在这里不能对其进行测试),但是值得一试