.net 传递列表';函数的枚举数
看起来,将列表的枚举数传递给函数“byval”与将其传递给函数“byref”完全不同。从本质上讲,常规的“byval”传递不会更改调用方的“enumerator.Current value”,即使函数使枚举数前进。我想知道是否有人知道为什么会这样?枚举数是一个类似于整数的基元,没有对象引用,因此对它的更改不会反映在调用方中吗 以下是示例代码: 此函数为byval,陷入无限循环,弹出“1”消息框,因为枚举数的“current”永远不会超过5:.net 传递列表';函数的枚举数,.net,vb.net,enumerator,.net,Vb.net,Enumerator,看起来,将列表的枚举数传递给函数“byval”与将其传递给函数“byref”完全不同。从本质上讲,常规的“byval”传递不会更改调用方的“enumerator.Current value”,即使函数使枚举数前进。我想知道是否有人知道为什么会这样?枚举数是一个类似于整数的基元,没有对象引用,因此对它的更改不会反映在调用方中吗 以下是示例代码: 此函数为byval,陷入无限循环,弹出“1”消息框,因为枚举数的“current”永远不会超过5: Public Sub listItemsUsingBy
Public Sub listItemsUsingByValFunction()
Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
Dim enumerator = list.GetEnumerator()
enumerator.MoveNext()
While enumerator.Current <= 5
listFirstItemByVal(enumerator)
End While
End Sub
Private Sub listFirstItemByVal(ByVal enumerator As List(Of Integer).Enumerator)
MsgBox(enumerator.Current)
enumerator.MoveNext()
End Sub
使用ByValFunction()的公共子列表项
作为(整数的)新列表的Dim列表(新整数(){1,2,3,4,5,6,7,8,9,10})
Dim枚举器=list.GetEnumerator()
枚举数。MoveNext()
While enumerator.Current您看到这种行为的原因是
List(Of T)。enumerator
是一个Struct
,而不是通常预期的类。因此,当您传递枚举数时,您传递了它的一个副本,因此当您调用MoveNext
时,使用所提供的示例代码将不会使用选项Strict On编译该副本。修正这一点可能会修正你所看到的差异
Public Sub listItemsUsingByValFunction()
Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
Dim enumerator As IEnumerator(Of Integer) = list.GetEnumerator()
enumerator.MoveNext()
Debug.WriteLine("S " & enumerator.Current)
Stop
Do
Debug.WriteLine("W " & enumerator.Current)
If Not listFirstItemByVal(enumerator) Then Exit Do
Loop
End Sub
Private Function listFirstItemByVal(ByVal enumerator As IEnumerator(Of Integer)) As Boolean
Debug.WriteLine("F " & enumerator.Current)
Return enumerator.MoveNext()
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
listItemsUsingByValFunction()
End Sub
有趣!谢谢你澄清这一点!所以,如果您将枚举数传递给函数,您是否总是在心里记下使用“byref”?例如,是否有一些解决方法可以避免总是记住这一点,特别是因为Visual Studio将自动生成总是使用byval的方法,因此这样的事情可能很容易被忽略?@MichaelZlatkovsky如果使用IEnumerator(Of T)
,则无需这样做,这是最常见的情况。每当我传递特定于类型的枚举数时,我总是在执行ByVal
vs.ByRef
之前检查类型,真的吗?我在原始代码中添加了“Option Strict On”,但仍然没有收到任何警告或错误。我应该说,Option Strict On,Option Inferre Off,Option Explicit On。抱歉。嗯,我没有意识到关闭推断功能会捕获未显示的错误(当我第一次设置项目时,我有点假设“打开”的东西越多越好!)在你看来,关闭推断功能是一种最佳实践吗?它不需要更多的输入吗?例如,它值得你这么做吗?我喜欢Option Strict On,Option Inferre Off,Option Explicit On。它更多的是打字,但它有助于捕捉像这样的错误。当你第一次花上几个小时去寻找一个错误,而这个错误是由一些你认为不是的东西引起的,这会让你信服。这很公平。顺便问一下,C#呢?您知道它是否有类似的“选项推断”开关吗?我已经看到越来越多的代码似乎确实使用了推断,但我不确定C#编译器是否有更好的“感觉”来推断什么是安全的,什么是不安全的。。。
Public Sub listItemsUsingByValFunction()
Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
Dim enumerator As IEnumerator(Of Integer) = list.GetEnumerator()
enumerator.MoveNext()
Debug.WriteLine("S " & enumerator.Current)
Stop
Do
Debug.WriteLine("W " & enumerator.Current)
If Not listFirstItemByVal(enumerator) Then Exit Do
Loop
End Sub
Private Function listFirstItemByVal(ByVal enumerator As IEnumerator(Of Integer)) As Boolean
Debug.WriteLine("F " & enumerator.Current)
Return enumerator.MoveNext()
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
listItemsUsingByValFunction()
End Sub