本文介绍了.NET:引用传递是谎言吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我遇到了一个有趣的情况,在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
推荐答案
我遇到了一个有趣的情况,其中按引用传递似乎在VB.NET中不起作用。
确实,这是一个相当有趣的案例。
我在下面提供了一些示例代码,供大家使用。有谁能解释这一现象。
是。
这是有意为之,还是语言/编译器有错误?
此行为是故意设计的,不是错误。您不应该像这样编写VB代码。如果执行此操作时感到疼痛,请停止操作。
这一切都是有道理的,但你必须理解其中的逻辑。跟随
- byref是变量的别名。也就是说,当您将一个变量传递给一个接受byref的方法时,形参将成为该变量的别名。我们有一个变量和两个名称。
- 属性不是变量。属性是一对方法:一个getter和一个setter。属性可以由变量支持,但属性不是变量。生成值的getter和接收值的setter。确保你对值和变量之间的区别很清楚。变量包含值。
- 如果尝试将属性传递给需要byref参数的方法,会发生什么情况?在C#中,这是非法的。在VB中,编译器为您生成一个临时变量,并使用Copy-In-Copy-Out语义通过ref传递它。也就是说,您的程序相当于:
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对引用传递的值的处理方式不同并不是偶然的!
C#的设计原则包括,编译器应该在代码看起来错误的时候告诉你,特别是编译器不应该通过猜测你的意思来"掩盖"问题,并发出代码让它在大部分时间里都能工作。设计团队认为C#程序员的态度是"编译器是我的朋友,当我犯错时,他会告诉我,这样我就可以改进"。
VB的设计原则包括代码可能工作得很好,如果有看起来不太正确的地方,找出用户的意思并使其工作,即使这意味着引入不保留对象标识的代码,或者添加隐藏的复制入复制出或其他任何东西。设计团队认为VB程序员的态度是"编译器经常挡住我的路;我已经表达了一个意图,所以让它发挥作用"。这两个设计原则都是完全合理的,每个原则都有大量的开发人员支持。我认为微软花了几十年的时间将语言开发的费用翻了一番,这样开发人员就有能力选择一种适合他们性格的语言,这是相当好的。
也就是说:在C#中,编译器会执行类似的操作:创建一个临时变量,为其赋值,然后通过引用传递该变量。挑战:创建一个证明这一事实的程序。
提示1:可变结构在C#中是一种糟糕的做法,这是有原因的。
提示2:在C#中,变量在什么情况下被视为值?
这篇关于.NET:引用传递是谎言吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!