VB.NET中,为何Property Setters的调用次数超出常规预期?
- 内容介绍
- 文章标签
- 相关推荐
本文共计719个文字,预计阅读时间需要3分钟。
在VB.NET中,我观察到一种行为,属性设置器被调用的次数似乎比必需的更多,并且还调用了姐妹setter方法。例如:
vbPublic Class Form1 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) End SubEnd Class
我在VB.net中观察到一种行为,其中属性设置器被调用的次数比看似必要的更多,并且调用了对姐妹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使用情况下的这种行为,但是最近发现了一种更加隐蔽的行为,这种行为导致重复调用的堆栈溢出,因为setter调用会更新一个调用的值.只有吸气剂.
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().这是让我困惑的二传手的自动召唤.
Dim temp = Me.ReferenceTypeData Me.WorkReferenceTypeByReference(temp) Me.ReferenceTypeData = temp
其他语言(如C#)不允许通过引用传递属性(正确地从参数传递的严格定义中传递),而是要求您自己编写上述代码的等效代码.
本文共计719个文字,预计阅读时间需要3分钟。
在VB.NET中,我观察到一种行为,属性设置器被调用的次数似乎比必需的更多,并且还调用了姐妹setter方法。例如:
vbPublic Class Form1 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) End SubEnd Class
我在VB.net中观察到一种行为,其中属性设置器被调用的次数比看似必要的更多,并且调用了对姐妹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使用情况下的这种行为,但是最近发现了一种更加隐蔽的行为,这种行为导致重复调用的堆栈溢出,因为setter调用会更新一个调用的值.只有吸气剂.
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().这是让我困惑的二传手的自动召唤.
Dim temp = Me.ReferenceTypeData Me.WorkReferenceTypeByReference(temp) Me.ReferenceTypeData = temp
其他语言(如C#)不允许通过引用传递属性(正确地从参数传递的严格定义中传递),而是要求您自己编写上述代码的等效代码.

