VB.Net中可重写属性上的速记符号不起作用
在我的VB.Net代码中,我知道当我在类中声明一个属性时,我可以使用缩写,例如,VB.Net中可重写属性上的速记符号不起作用,vb.net,class,oop,Vb.net,Class,Oop,在我的VB.Net代码中,我知道当我在类中声明一个属性时,我可以使用缩写,例如,公共属性Prop1 As String,.Net自动创建一个私有变量\u Prop1,我可以在类中引用它 我还知道,我可以使用\u Prop1或Prop1在代码中引用该变量 现在,由于我一直认为首选方法是使用私有变量,所以我一直尝试在类中引用\u Prop1进行修改/编写代码。这就是我现在的问题所在 我有以下情况: Public Class MyClass_Base Public Overridable Pro
公共属性Prop1 As String
,.Net自动创建一个私有变量\u Prop1
,我可以在类中引用它
我还知道,我可以使用\u Prop1
或Prop1
在代码中引用该变量
现在,由于我一直认为首选方法是使用私有变量,所以我一直尝试在类中引用\u Prop1
进行修改/编写代码。这就是我现在的问题所在
我有以下情况:
Public Class MyClass_Base
Public Overridable Property Prop1 As String = "val1"
Public Sub Test()
If _Prop1 = ....
End Sub
End Class
Public Class MyClass
Inherits MyClass_Base
Public Overrides Property Prop1 As String = "val2"
End Class
基本上,我在基类中将属性定义为可重写,现在当我进入Test()
子例程时,\u Prop1
的值为Nothing
。但是Prop1
具有正确的值val2
编程大师们,处理这种情况的正确方法是什么?
我是否忽略了自动创建的prive变量\u Prop1
并与公共Prop1
一起工作,或者是否有其他东西我应该添加/甚至不使用简写符号,并编写我自己的getter/setter逻辑以确保事情按照我的意愿进行更改
谢谢 我想你已经回答了你自己的问题。您绝对不应该在自己的代码中依赖隐藏的编译器机制。您正在引用一个未声明的变量,并且在框架中无法保证该变量会存在(或者按照您的预期工作,正如您所发现的那样)-使用它是一种黑客行为,因此不要这样做 除非您有很好的理由不这样做,否则类中的代码应该引用公共属性,就像使用该类的代码一样。如果您使用的是自动属性,那么这样做与使用私有变量没有区别。它还有一个好处,就是如果您稍后决定实现显式的getter和setter,那么代码不会中断,新的getter和setter也会被调用 要探究您获得意外结果的原因,请在
Public Overrides Property Prop1 As String = "val2"
您将得到两个不同的\u Prop1
变量-MyClass\u Base.\u Prop1
和MyClass.\u Prop1
。然后调用Test()
时,调用的是基类方法,该方法将引用基类的\u Prop1
变量,该变量在重写子类中的隐式变量getter和setter后未设置为任何值
为了说明这一点,这类似于:
Public Class MyClass_Base
Private _Prop1 As String = "val1"
Public Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
Public Class MySubClass
Inherits MyClass_Base
Private _Prop1 As String = "val2"
End Class
Sub Main()
Dim class1 As New MyClass_Base
Dim class2 As New MySubClass
class1.Test()
class2.Test()
End Sub
您的输出将在哪里:
val1
val1
在上面的例子中,MyClass\u Base.\u Prop1
总是初始化的,但是在您的例子中,它不是。在任何一种情况下,Test()
方法都属于基类,因此它总是引用自己的\u Prop1
,而不是子类中声明的任何同名变量
如果您确实需要引用私有字段,无论出于何种原因,您都必须非常小心如何使用它(以及随之而来的含义)。如果子类打算以相同的方式使用它们自己的私有变量,那么任何这样做的方法本身都需要是可重写的。不是建议您继续使用隐式变量,而是为了证明:
Public Class MyClass_Base
Public Overridable Property Prop1 As String = "val1"
Public Overridable Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
Public Class MySubClass
Inherits MyClass_Base
Public Overrides Property Prop1 As String = "val2"
Public Overrides Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
这里我们得到了“预期”的结果,因为MySubClass
覆盖测试以引用它自己的私有字段。最好只使用属性名。从:
“为属性指定的属性不适用于支持字段。”
这是C#和VB.NET需要对齐的领域之一
C#(正确)不允许您访问自动实现的属性备份字段(没有一些复杂的工作)。我真的不知道你能用VB访问什么
因此,这里的规则是,即使您可以访问自动实现的属性的backing字段,您也不应该直接修改它(也不应该这样做)
如果需要,则应使用已定义的支持字段(带有初始化)和显式Get
和Set