gpt4 book ai didi

vb.net - 为什么 Property Setter 被调用的次数比预期的要多?

转载 作者:行者123 更新时间:2023-12-05 00:02:37 25 4
gpt4 key购买 nike

我在 VB.net 中观察到一个行为,其中属性 setter 被调用的频率比看起来需要的要多,结合对姊妹 setter 方法的调用。

Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Console.WriteLine("Calling WorkReferenceTypeByReference")
WorkReferenceTypeByReference(ReferenceTypeData)
Console.WriteLine("Called WorkReferenceTypeByReference")
Console.WriteLine("Calling WorkReferenceTypeByValue")
WorkReferenceTypeByValue(ReferenceTypeData)
Console.WriteLine("Called WorkReferenceTypeByValue")
End Sub

Public Sub WorkReferenceTypeByReference(ByRef ref As Point)
Dim b As Point = New Point(4, 4) + ref
Console.WriteLine(" adding (4,4) to " & ref.ToString)
End Sub

Public Sub WorkReferenceTypeByValue(ByVal ref As Point)
Dim b As Point = New Point(4, 4) + ref
Console.WriteLine(" adding (4,4) to " & ref.ToString)
End Sub

Private m_ReferenceType As Point = New Point(0, 0)
Public Property ReferenceTypeData As Point
Get
Console.WriteLine(" Calling ReferenceTypeData getter")
Console.WriteLine(" returning: " & m_ReferenceType.ToString)
Return m_ReferenceType
End Get
Set(ByVal value As Point)
Console.WriteLine(" Calling ReferenceTypeData setter")
Console.WriteLine(" value = " & value.ToString)
m_ReferenceType = value
End Set
End Property
End Class

前面的代码返回到控制台以下输出
Calling WorkReferenceTypeByReference
Calling ReferenceTypeData getter
returning: {X=0,Y=0}
adding (4,4) to {X=0,Y=0}
Calling ReferenceTypeData setter
value = {X=0,Y=0}
Called WorkReferenceTypeByReference
Calling WorkReferenceTypeByValue
Calling ReferenceTypeData getter
returning: {X=0,Y=0}
adding (4,4) to {X=0,Y=0}
Called WorkReferenceTypeByValue

请注意方法执行后对属性 setter 的虚假调用。我假设这种行为是作为一种安全措施来防止无意中修改基础属性的,尽管这可能是意图。

通过选择适当的 ByVal 关键字,可以轻松解决 ByRef 与 ByVal 使用情况下的这种行为,但是 hase 最近注意到一种更阴险的行为,该行为导致重复调用的堆栈溢出,因为 setter 调用会更新调用只有 setter/getter 。
Public Sub DoSomething()
Dim a As New CustomObject(anotherObject.AProperty(getterArgument))
End Sub

Public Class AnotherObject

Public Property AProperty as SomeType
Get
' Get value
End Get
Set
' Set value, call DoSomething
End Set
End Property
End Class

在前面的示例中,调用 DoSomething() 将触发 AProperty getter 方法,但在使用之后,将触发 setter 方法,该方法通过程序逻辑再次调用 DoSomething()。令我困惑的是 setter 的自动调用。

最佳答案

这实际上是 VB.Net 的一个特性。在您的代码中,您通过引用传递一个属性,而不是一个变量。严格来说,传递属性 ByRef 是不可能的,因为 ByRef 需要对变量的引用。但是,编译器会自动代表您创建一个临时本地并将其传递给您的方法。由于该方法可能会更改 ByRef 参数,该参数现在是编译器生成的临时参数,而不是您的属性,因此编译器随后会插入对 setter 的调用。本质上,会发生这样的事情:

Dim temp = Me.ReferenceTypeData
Me.WorkReferenceTypeByReference(temp)
Me.ReferenceTypeData = temp

其他语言,例如 C#,不允许通过引用传递属性(从参数传递的严格定义来看是正确的),而是要求您自己编写与上述代码等效的代码。

关于vb.net - 为什么 Property Setter 被调用的次数比预期的要多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7743109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com