vba 公共变量和属性之间的VBA区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24510264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 03:39:48  来源:igfitidea点击:

VBA difference between public variable and property

vbaclassooppropertiesinterface

提问by Toxiro

What is the difference between

之间有什么区别

Public Variable As Integer

and

Private pVariable As Integer

Public Property Let Variable(ByVal lVariable As Integer)
    pVariable = lVariable
End Property

Public Property Get Variable()
    Variable = pVariable
End Property

in a VBA class module?

在 VBA 类模块中?

And why would I use the second version?

为什么我会使用第二个版本?

回答by

As much as VBA is object-oriented it's still limited in many ways, but as far as this example goes it should be sufficient to just understand the basics of the OOP in VBA.

尽管 VBA 是面向对象的,但它仍然在许多方面受到限制,但就本示例而言,仅了解 VBA 中 OOP 的基础知识就足够了。

Your code

你的代码

Private pVariable As Integer

Public Property Let Variable(ByVal lVariable As Integer)
    pVariable = lVariable
End Property

Public Property Get Variable()
    Variable = pVariable
End Property

is wronga bit unnecessary.

错的有点不必要

NOTE: You may do that in cases where you want to handle errors / validate data coming in but generally if it's as simple as setting and getting the value you wouldn't do that.

注意:如果您想处理错误/验证传入的数据,您可以这样做,但通常如果它像设置和获取值一样简单,您就不会这样做

Why would you ever need a private backing field if you are exposing both the Let/Set and Get properties? All you need for this is the public variable itself and no need for properties.

如果您同时公开 Let/Set 和 Get 属性,为什么还需要私有支持字段?为此,您只需要公共变量本身,不需要属性。

The story changes 360 degrees when you have to only expose one of the properties and not the other (ie. either setter or getter only ). Maybe it's easier to understand by working through an example...

当您只需要公开一个属性而不公开另一个属性(即 setter 或 getter only )时,故事就会发生 360 度的变化。也许通过一个例子更容易理解......

Example

例子

Let's start by working through an easy "banking" example (obviously you wouldn't do that in VBA in real-life but it's a good concept to evaluate as a base)

让我们从一个简单的“银行”示例开始(显然你不会在现实生活中的 VBA 中这样做,但作为基础评估是一个好概念

Imagine you have to build a class to simulate a bank account. You need a way to depositand withdrawmoney from the account as well display balance.

想象一下,您必须构建一个类来模拟银行帐户。您需要一种方式depositwithdraw资金从帐户以及显示balance

Normally you wouldn'thave a setterfor the balancefield because no-one should be allowed to explicitly setthe balance. (if you know a bank that allows this please let me know ;)) . The actual balance should be a privatevariable. There should be a property which exposes it and that's all you should consider here.

通常你不会setterbalance字段,因为没有人应该被允许明确set的平衡。(如果您知道允许这样做的银行,请告诉我;))。实际余额应该是一个私有变量。应该有一个公开它的属性,这就是您在这里应该考虑的全部内容。

Consider a VBA class (an interface)

考虑一个 VBA 类(一个接口)

IAccountServices.cls

IAccountServices.cls

Sub Deposit(amount As Double)
End Sub

Sub WithDraw(amount As Double)
End Sub

and another class to represent the account

和另一个代表帐户的类

Account.cls

帐户.cls

Implements IAccountServices

' balance should be private
' cause you should only have a getter for it
' you should only be able to set the balance inside this class
' based on the operations
Private accBalance As Double

' see Getter only - no setter
Public Property Get Balance() As Double
    Balance = accBalance
End Property

Public Function Deposit(amount As Double)
    accBalance = accBalance + amount
End Function

Public Function WithDraw(amount As Double)
    accBalance = accBalance - amount
End Function

Private Sub IAccountServices_Deposit(amount As Double)
    accBalance = accBalance + amount
End Sub

Private Sub IAccountServices_WithDraw(amount As Double)
    accBalance = accBalance - amount
End Sub

NOTE: This obviously is the simplest of simple examples and it does not have any error handling or checking whether the balance is sufficient to withdraw etc. This is just for demonstration purposes and not to be used in a real-life application.

注意:这显然是最简单的简单示例,它没有任何错误处理或检查余额是否足以提取等。这仅用于演示目的,不适用于实际应用程序。

With this encapsulation I see/know right away

通过这种封装,我立即看到/知道

  • accBalanceis a private field not accessible anywhere outside the class.

  • I can only retrieve the balance()and not explicitly set it on an instance of the Accountclass.

  • I can deposit()and withdraw()money from the account (publicly accessible methods)

  • accBalance是一个私有字段,在课堂之外的任何地方都无法访问

  • 我只能检索balance()而不是在Account类的实例上显式设置它。

  • 我可以deposit()withdraw()账户中的钱(可公开访问的方法)



In you standard module (module1) even with intelli-sense you get the .Balance listed and that's all your library/class user ever have to worry about.

在您的标准模块 (module1) 中,即使使用智能感知,您也会列出 .Balance,这就是您的图书馆/班级用户所需要担心的。

Now having a standard coding module to test both classes (Module1)

现在有一个标准的编码模块来测试两个类(模块 1)

Sub Main()

    Dim myAccount As Account
    Set myAccount = New Account

    Debug.Print "Starting Balance: " & myAccount.Balance

    myAccount.Deposit (2000)
    Debug.Print "Deposited: 2000"

    myAccount.WithDraw (250)
    Debug.Print "Withdrew: 250"

    Debug.Print "Ending Balance: " & myAccount.Balance

    ' can't set balance
    ' myAccount.Balance = 999999999999999999999999
End Sub

To get an intro to VBA OOP I could recommend:

要获得 VBA OOP 的介绍,我可以推荐:

回答by riderBill

A property allows external access as though the property was a public field, while allowing the class to keep control of the data.

一个属性允许外部访问,就好像该属性是一个公共字段,同时允许类保持对数据的控制。

The Get property may compute a "variable" that doesn't actually exist in the class. E.g. a mass Get propertymight return the product of density times volume.

Get 属性可能会计算类中实际不存在的“变量”。例如,mass Get 属性可能会返回密度乘以体积的乘积。

Private density as Double
Private volume as Double
Private potentialEnergy

Public Property Get mass() As Double
   mass = density*volume
End Property 'Property Get mass

A Letproperty might check validity, e.g. not accept a negative volume. Or it can keep an object's field properties in sync:

一个财产可能会检查的有效性,如不接受负积。或者它可以保持对象的字段属性同步:

Public Property Let density(rho as Double)
   if rho > 0 then
      density = rho
      potentialEnergy = density * volume * gravity * height
End Property 'Property Get mass

You can also make a property read-only (or write-only -- not used much) by omitting the Let or Get property.

您还可以通过省略 Let 或 Get 属性将属性设为只读(或只写——很少使用)。

Other than a very slight degradation in performance, it's good practice to use properties from the start for any fields that you allow public access, even if the properties are initially trivial, to facilitate future modifications to the class.

除了非常轻微的性能下降之外,最好从一开始就对允许公共访问的任何字段使用属性,即使这些属性最初是微不足道的,以方便将来对类进行修改。