在我的VB.Net代码中,我知道当我在类中声明一个属性时,我可以使用简写,例如,Public Property Prop1 As String
和.Net自动创建一个私有变量{{1}我可以在课堂上引用。
我也知道我可以使用_Prop1
或_Prop1
在我的代码中引用该变量。
既然我一直认为首选方法是使用私有变量,我总是试图在我的类中使用Prop1
进行修改/编写代码。这就是我现在遇到的问题......
我有以下情况:
_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()
的值为_Prop1
。但是,Nothing
的值为Prop1
。
在那里编程专家,处理这种情况的正确方法是什么?
我是否会忽略自动创建的prive变量val2
并使用公共_Prop1
,或者是否还有其他我应该添加/甚至不使用简写表示法来编写我自己的getter / setter逻辑确保事情按照我的意愿改变?
感谢!!!
答案 0 :(得分:1)
我想你已回答了自己的问题。你绝对不应该依赖自己代码中隐藏的编译器机制。你引用了一个你没有声明的变量,并且框架中没有保证这个变量会存在(或者像你所发现的那样工作) - 这是一个使用它的黑客,所以不要吨。
除非你有充分的理由不这样做,否则类中的代码应该引用公共属性,就像使用类的代码一样。如果您正在使用自动属性,则执行此操作与使用私有变量之间没有区别。它还有一个好处,如果你以后再决定实现显式的getter和setter,你的代码不会破坏,并且你的新getter和setter会被调用。
在声明
时,探究获得意外结果的原因 Public Overrides Property Prop1 As String = "val2"
您最终会得到两个不同的_Prop1
变量 - MyClass_Base._Prop1
和MyClass._Prop1
。然后当你调用Test()
时,你正在调用基类方法,它将引用基类的_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_Base._Prop1
总是被初始化,但在你的情况下,它不是。在任何一种情况下,Test()
方法都属于基类,所以它总是引用它自己的_Prop1
而不是在子类中声明的同名变量。
如果你确实需要引用私人领域,无论出于何种原因,你必须非常小心你是如何做到的(以及后面的含义)。如果子类旨在以相同的方式使用它们自己的私有变量,那么执行此操作的任何方法本身都需要Overridable
。不是建议你应该继续使用隐式变量,而是要证明:
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
会覆盖test以引用自己的私有字段。最好只是坚持使用属性名称。
答案 1 :(得分:1)
来自documentation on Auto Implemented Properties:
“为该属性指定的属性不适用于支持字段。”
这是需要对齐C#和VB.NET的领域之一。
C#(正确)不允许您访问自动实现的属性支持字段(没有一些复杂的工作)。老实说,我不知道你可以在VB中访问它。
所以这里的规则即使您可以访问自动实现的属性的支持字段,您也不应该直接修改它(也不需要)
如果您需要,那么您应该使用已定义的支持字段(带初始化)和明确的Get
和Set