【问题标题】:Why to use GET & SET methods while defining properties in VB.Net?为什么在 VB.Net 中定义属性时使用 GET 和 SET 方法?
【发布时间】:2021-05-27 02:37:07
【问题描述】:

我对在 VB.net 中使用 GET 和 SET 方法的需要感到有些困惑。我想在这方面讨论两种情况:第一种是将属性声明为 PUBLIC 时,然后将属性声明为 PRIVATE 时。

我发现当我将一个属性定义为公共时,我可以直接设置和访问该属性的值,而无需使用 GET/SET 方法 --- 非常简单:见下文

Module Program
    Sub Main()
        Dim t As New test()
        t.name = "Roy" 'Label 1
        Console.WriteLine("t.name = {0}", t.name)
        Console.ReadLine()
    End Sub
End Module

Class test
    Public Property name() As String
End Class

当我将相同的属性声明为私有时,如下所示,我仍然可以通过简单地使用构造函数和公共子例程来设置和访问私有属性的值。见下文:

Module Program
    Sub Main()
        Dim t As New test()
        t.printValue()
        Console.ReadLine()
    End Sub
End Module

Class test    
    Private Property Name() As String 
    Sub New()
        Name = "Roy" 'Label 2
    End Sub

    Public Sub printValue()
        Console.WriteLine("Value stored in NAME is: {0}", Name)
    End Sub
End Class

所以我的问题是为什么我们需要使用 GET/SET 方法?我知道每当对属性进行赋值时,都会隐式调用 SET 方法……但是您能帮我理解我们必须显式使用 GET/SET 方法的情况吗?还是使用 GET/SET 是一种选择?如果使用 GET/SET,验证是可以在稍后阶段轻松添加的一件事,但那是唯一的原因吗? PL 给出你的意见。

此外,我在 stackoverflow 中遇到了以下两个相关问题(尽管针对不同的语言):链接如下:

Why to use getter and setter methods to set class properties?

Why use getters and setters/accessors?

但我无法理解证明使用 GET/SET 方法的大部分原因。例如,如果我们不使用 GET/SET 方法,那么我们会将属性暴露给外部世界——这意味着它可以从类外部直接访问。但这仅适用于 PUBLIC 属性,因为不能从类外部直接访问 PRIVATE 属性。同样,在第二个链接中,作者提到以下作为使用 GET/SET 的原因:为运行时属性更改时提供调试拦截点 - 调试属性更改为特定值的时间和地点可以在某些语言中如果没有这个就很难了。这到底是什么意思——任何简单的现实生活例子?

【问题讨论】:

  • 请注意,即使在您没有看到GetSet 例程的情况下,它们仍然存在——VB 只是自动生成它们。如果您愿意,您甚至可以分配给代码中的支持字段。在您的示例中,有一个名为 _Name 的隐式定义字段。隐式定义的Get 例程从该字段中检索其值,隐式定义的Set 例程将新值分配给该字段。
  • 至于你的粗体:当你有明确的GetSet例程时,你可以在例程中设置一个调试器断点,然后如果你在调试器中运行,每次你的代码进入例行程序,就会中断。通常,您会想要这样做,因为您不了解它何时/如何发生。使用您的代码,想象稍后某个时间,您检查Name,并找到“Siegfried”。你以为它是“罗伊”。您可以在 Set 例程中设置断点,以便了解它是如何更改的。

标签: vb.net


【解决方案1】:

属性是字段的包装,即类或结构变量。它提供了一个 getter 和/或一个 setter 方法来访问这个变量。 (您也可以有一个只读属性,返回未绑定到单个字段的简单评估结果。)

getter 和 setter 在读取和写入属性时被隐式调用。

所以,问题不在于是否使用 getter 和 setter,而是直接访问字段还是通过属性访问字段。

您可以通过声明一个字段并显式编写 getter 和 setter 来声明这样的属性。

Private _prop1 As String ' Backing field
Public Property Prop1() As String
    Get
        Return _prop1
    End Get
    Set(ByVal value As String)
        _prop1 = value
    End Set
End Property

或使用Auto-Implemented Property

Public Property Prop1 As String

两个声明是等价的。自动实现的属性隐式声明了一个支持字段,并相应地实现了 getter 和 setter。

当你只在声明它的类中使用它时,将它声明为私有是有意义的。这仍然提供了您提供的链接中描述的优势,因为此属性仍然隐藏了访问字段、进行验证等的详细信息;但是,它并不禁止直接访问类内的支持字段。因此,您需要更加自律地处理私有财产。


属性对于调试意味着什么?您可以轻松地在 getter 或 setter 中设置断点,以检测对属性的访问。您不能在字段上设置断点,因为从不执行字段。这只是一个声明。

您还可以添加System.Diagnostics.Debug.Writeline("=====> test")(写入输出窗口)或登录getter和setter。

另见:Tutorial: Learn to debug Visual Basic code using Visual Studio


使用Windows Forms Data BindingWPF Data Binding 时需要属性。他们还允许change notification

【讨论】:

    【解决方案2】:

    动态计算值

    我没有阅读这些链接,但您可能想要实现自己的 getter 和 setter 的一个原因是您可能想要返回需要某种类型的计算或操作的东西。例如,假设您的项目 Sale 具有属性 RawPriceSalesTaxFinalPrice。但是,您需要/选择每次动态计算最终价格(基于可变销售税)。因此,您首先设置 RawPrice,然后查询 FinalPrice,它返回 RawPrice + SalesTax,但 SalesTax 会根据其他一些属性(如原产国等)动态计算。

    数据的替代视图

    您可能想要这样做的另一个原因是提供相同核心数据的另一个视图。例如,如果您的数据是 HTML 页面,可能一个属性返回正常的字符串值,而另一个“非 HTML”Property 有一个自定义 Getter,它执行一些正则表达式以删除所有 HTML 标记并返回纯文本变体。这允许您将所有相关代码保留在子程序集中,而不是让您的主程序进行各种操作。

    代码可移植性

    由于代码可移植性,这可以让您的生活变得更轻松。您的代码现在更容易在其他项目中重用,因为您只需要一个程序集。

    私有变量与属性

    如果我正在做一些需要具有类似属性的类的事情,那么很有可能它也会有方法。这些方法几乎总是需要创建程序集之外不需要知道的私有变量。但是,在这种情况下,它们不会是私有属性,而只是私有变量。例如,与 Private Property Name() As String 相比,它隐含的带有 getter 和 setter 的自动实现的支持变量,我只想说 Private Name() As String,这将等同于 Dim Name() As String。您可以像往常一样在您的类中使用变量、常量等,并且默认情况下,世界其他地方不会知道它们的任何信息。

    我不确定您为什么要使用私有财产。也许有充分的理由;我只是不知道它是什么。大多数时候,私有变量可能是您真正想要的。如果您认为您确实需要私有财产是有原因的,我很想听听您对此的想法。 (我总是乐于接受新的思维方式!)

    历史

    多年以来,Visual Basic .NET 中都没有自动实现的属性。过去,您别无选择,只能使用 GET/SET。因此,VB.NET 的最新发展是能够像在第一个代码示例中那样简单地声明属性,并让运行时自动生成支持变量。

    【讨论】:

    • 我错误地将该属性设为私有。您指出这一点是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    相关资源
    最近更新 更多