我遇到了一个有趣的情况,即按引用传递在VB.NET中似乎不起作用。我在下面提供了一些示例代码供大家使用。谁能解释这个现象。这是故意的,还是语言/编译器存在错误?
我在这段代码中看到的是“增量后”读数与“增量前”读数相同。
Public Class Wrapper
Public Property Value As Integer
End Class
Sub Main()
Dim rand As New Random()
Dim w As New Wrapper()
w.Value = rand.Next()
Console.WriteLine("Before Increment: {0}", w.Value)
Try
Increment(w.Value)
Catch ex As Exception
End Try
Console.WriteLine("After Increment: {0}", w.Value)
Console.ReadLine()
End Sub
Public Sub Increment(ByRef i As Integer)
i += 1
Throw New Exception()
End Sub
答案 0 :(得分:20)
我遇到了一个有趣的情况,即按引用传递在VB.NET中似乎不起作用。
实际上,这是一个很有趣的情况。
我在下面提供了一些示例代码供大家使用。谁能解释这个现象。
是的
这是故意的,还是语言/编译器存在错误?
此行为是设计使然,不是错误。 您不应编写这样的VB代码。如果这样做时很痛,请停止这样做。
这一切都说得通,但是您必须了解它的逻辑。跟随
Try
Dim Temp As Integer
Temp = w.Value ' copy-in
Increment(Temp) ' make an alias to Temp
w.Value = Temp ' copy-out
Catch ex As Exception
End Try
现在应该很清楚为什么您的程序具有其行为。 抛出发生在复制之前。
人们经常说C#和VB是具有不同语法的“同一语言”,这有些道理。但是,显示出小的差异的示例说明了这些语言具有不同的设计原理。 C#和VB对ref传递的值的处理不同并不是偶然的!
C#的设计原则包括:编译器应在代码看起来不正确时告诉您,尤其是编译器不应通过猜出您的意思并“散布”代码来“解决”问题,从而使它在大多数情况下都能正常工作。时间。设计团队将C#程序员的态度视为“编译器是我的朋友,谁会告诉我什么时候出错,所以我可以改进”。
VB的设计原则包括:代码可能工作得很好,并且,如果有些东西看起来不太正确,请弄清楚用户的意思并使之起作用,即使这意味着要引入例如“保留对象身份,或添加隐藏的复制中复制或其他内容。设计团队认为VB程序员的态度是:“编译器经常妨碍我;我已经表达了要使其工作的意图。”
这两种设计原则都是完全明智的,每种设计原则都有很大的开发者群体。我认为,微软花了数十年的时间将语言开发的费用增加了一倍,使开发人员能够选择适合其性格的语言,这是非常好的。
也就是说,在C#中,编译器会做类似的事情:创建一个临时变量,给它赋一个值,然后由ref传递该变量。
挑战:创建一个演示此事实的程序。
提示#1:由于某种原因,可变结构在C#中是一种不好的做法。
提示2::什么情况下变量在C#中被视为值?