刚才我很震惊地发现以下内容是合法的(C# 等效项绝对不合法):
Class Assigner
''// Ignore this for now.
Public Field As Integer
''// This part is not so weird... take another instance ByRef,
''// assign it to a different instance -- stupid but whatever. '
Sub Assign(ByRef x As Assigner, ByVal y As Assigner)
x = y
End Sub
''// But... what's this?!?
Sub AssignNew()
''// Passing "Me" ByRef???
Assign(Me, New Assigner)
End Sub
''// This is just for testing.
Function GetField() As Integer
Return Me.Field
End Function
End Class
但是更奇怪的是对我来说同样奇怪的是它似乎没有做我所期望的:
Dim a As New Assigner With {.Field = 10}
a.AssignNew()
Console.WriteLine(a.GetField())
上面的输出是“10”,而不是我想象的“0”(当然,这种期望本身就充满了某种恐怖)。所以看起来你可以通过
Me
ByRef
,但是编译器以某种方式覆盖(?)该行为,就像你已经通过了Me
ByVal
。
Me
ByRef
是合法的?(有向后兼容的解释吗?)
(都是我的重点)11.4.3 实例表达式
实例表达式是关键字
Me
、MyClass
或MyBase
。实例表达式只能在非共享方法、构造函数或属性访问器的主体中使用,被归类为value。9.2.5.2 参考参数
如果传递给引用参数的变量类型与引用参数的类型不兼容,或者如果将非变量作为参数传递给引用参数,则可以分配临时变量并将其传递给引用参数。参考参数。传入的值将在调用方法之前复制到此临时变量中,并在方法返回时复制回原始变量(如果有)。
因此,编译器将创建一个分配给
Me
值的临时变量,以作为
ByRef
参数传递。返回时,不会复制结果值,因为
Me
不是变量。
Class Assigner
''// Methods
Public Sub Assign(ByRef x As Assigner, ByVal y As Assigner)
x = y
End Sub
Public Sub AssignNew()
Dim VB$t_ref$S0 As Assigner = Me
Me.Assign((VB$t_ref$S0), New Assigner)
End Sub
Public Function GetField() As Integer
Return Me.Field
End Function
''// Fields
Public Field As Integer
End Class
所以看起来当你调用AssignNew()时,你正在将新实例分配给内部生成的变量。 “a”变量不会被触及,因为它甚至不是函数的一部分。
他们错过了这个。
BAM突然间你就进入了一个完全不同的对象!那太糟糕了!如果您打算这样做,您不妨编写一段 MS-Basic 行号代码,其中所有全局变量都是随机设置的,并且没有子函数/函数。 如果您在括号中传递参数,其工作方式是相同的。例如,这按预期工作:
Assign(Reference_I_Want_To_Set, New Assigner)
但这并没有改变任何事情:
Assign((Reference_I_Want_To_Set), New Assigner)
如果您按照 adam101 的建议反映上述类型的代码,您将看到类似的结果。虽然这对括号来说是巨大的挫败感,但对于
Me
来说这是一件非常好的事情!!!要使此代码正常工作,您需要做的是:
Class Assigner
''// Ignore this for now.
Private newPropertyValue As Integer
Public Property NewProperty() As Integer
Get
Return newPropertyValue
End Get
Set(ByVal value As Integer)
newPropertyValue = value
End Set
End Property
''// This part is not so weird... take another instance ByRef,
''// assign it to a different instance -- stupid but whatever. '
Shared Sub Assign(ByRef x As Assigner, ByVal y As Assigner)
x = y
End Sub
''// But... what's this?!?
Shared Sub AssignNew(ByRef x As Assigner)
''// Passing "Me" ByRef???
Assign(x, New Assigner)
End Sub
End Class
然后像这样使用它
Dim a As New Assigner With {.NewProperty = 10}
Assigner.AssignNew(a)
我的理解是您在使用对象时无法更改对象的引用,因此您需要在共享子中更改它
由于
不能成为赋值的目标,代码似乎创建了它的副本,从那时起,您不再使用真实的对象,而是它的副本