有没有办法将 ParamArray 值作为 byRef 处理,以便可以更新它们?
听起来很简单,但它不起作用。 在此示例中,我想将 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
参数数组中的值没有在返回中更新! 我期望现在所有的最终值都是“1”,就像它们在函数中一样。
有没有办法获得像这样的可更新的 ParamArray 集合? ParamArray 必须声明为 ByVal,但是对于像 String 这样的引用类型,难道不应该只制作指针的副本并允许我更改基础值吗?
有没有更好的方法来得到我想要的东西? (C# 不是一个选项)。
Sounds simple enough, but its not working. In this example, I want to set the values of 3 fields to equal a 4th. I could do something like this....
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
... but that's kind of wordy (yeah, I know, vb is wordy in most cases). I would like to have something I can use to reduce this to a single line call, so I made this extension method.
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
Seems straightforward enough, right? Well, the output is this...
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
Values in the param array did not get updated in the return! I was expecting to have all of the final values now be "1", like they are in the Function.
Is there any way to get an update-able ParamArray collection like this? ParamArray must be declared ByVal, but with a reference type like String, shouldn't that only make a copy of the pointer and allow me to change the underlying value?
Is there a better way to get what I want? (C# is not an option for this).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ParamArray 无法实现您想要做的事情。 当您调用 ParamArray 方法时,会在后台发生以下情况
没有调用后操作将值从数组复制回并传递到传入的原始变量中。
让函数修改值并在调用站点看到它的唯一可靠方法是传递值 ByRef。 您可以使用一些魔法来拥有一组采用 ByRefs 的重载,手动转换为数组,然后复制回来。 但这是你能得到的最接近的结果。
What you're trying to do cannot be achieved with ParamArray. When you call a ParamArray method the following occurs under the hood
There is no post call operation that will copy the values back out of the array and into the original variables that were passed in.
The only reliable way to have the function modify a value and have it seen at the call site is to pass the value ByRef. You could do a bit of magic to have a set of overloads which take ByRefs, manually convert to an array and then does a copy back. But that's the closest you're going to get.
对于这个例子来说可能有点晚了(几乎 10 年前),但如果它有效的话可能会帮助其他人...
您不能将参数数组作为引用传递,但可以将数组作为引用传递。
将其更改为 ByRef 并删除 ParamArray
然后修改此行:
只需记下附加的“{”和“}”即可将字符串传递为Array 而不是 ParamArray
我在类中使用它来传递控件数组并且它有效(ParamArray 没有)所以我希望(无法在这里测试它)但它可能值得一试
Might be a bit late for case in point (almost 10 years ago) but might help someone else if it works...
You cannot pass parameter-array as reference, but you can pass an array as reference.
Change it to ByRef and remove ParamArray
Then modify this line:
Just take note of the additional "{" and "}" to pass strings as Array rather than ParamArray
I used this in a class to pass an array of controls and it worked (where ParamArray did not) so I'm hoping (cannot test it here) but it might be worth a shot