17

我刚刚发现 Me 关键字无法访问私有过程,即使它们位于其自己的类模型中。

在 Class1 中取以下代码:

Private Sub Message()
    Debug.Print "Some private procedure."
End Sub

Public Sub DoSomething()
    Me.Message
End Sub

此代码实例化该类的一个实例:

Sub TestClass()
    Dim objClass As New Class1
    objClass.DoSomething
End Sub

Me.Message抛出编译错误“找不到方法或数据成员”。

如果我改变Private Sub Message()程序Public工作正常。我也可以从 DoSomething 过程中删除 Me 关键字,但我的印象是 Me 关键字背后的想法是确保 Class1 的多个实例被正确封装。

为什么VBA Me关键字不能访问自己模块中的私有程序?省略 Me 关键字并在课堂上做这样的事情是否安全?

Private Sub Message()
    Debug.Print "Some private procedure."
End Sub

Public Sub DoSomething()
    Message
End Sub

谢谢!

更新:感谢有关正确语法的提示,我的代码正在运行。我仍在寻找解释为什么我可以在它自己的模块的实例中引用私有过程。我找不到任何好的文档。

4

5 回答 5

9

任何关于它为什么设计成这样的猜测都是纯粹的假设,无需与设计师交谈。但我自己的猜测是,Me关键字返回对代码当前正在执行的对象的引用。我猜测与其创建一个特殊情况Me,他们发现继续遵守对象的范围规则更容易。也就是说object.method只能在公共或朋友方法上工作。所以Me, 正是它所说的,当前正在执行的对象的一个​​实例。而且由于 VBA/VB6 没有共享方法,因此是否使用前缀Me并不重要。

但如果它让你感觉更好,我也觉得它非常令人讨厌。

于 2009-12-15T16:09:11.070 回答
3

您不需要Me关键字在自己的类中调用。

于 2009-12-13T05:35:15.947 回答
1

我就是这个类的对象实例。所以除了这个类的公共函数或子函数之外,没有人可以直接调用私有子函数或函数或访问私有变量。

于 2013-01-12T12:29:01.850 回答
1
Public Function Fight() As String
'performs a round of attacks i.e. each character from both sides performs an attack
'returns a scripted version of the outcomes of the round

'check if buccaneers are all dead
If mBuccaneers.aliveCount > 0 Then

    'check if any hostiles are alive
    If mHostiles.aliveCount > 0 Then

        'check we have some buccaneers
        If mBuccaneers.count = 0 Then
            Fight = "There are no buccaneers. Load or create some buccaneers"
        Else
            If mHostiles.count = 0 Then
                'can't fight
                Fight = "There are no hostiles to fight. Generate some hostiles"
            Else
                mScript = ""
                Call GroupAttack(mBuccaneers, mHostiles)
                Call GroupAttack(mHostiles, mBuccaneers)
                Fight = mScript
            End If
        End If

    Else 'hostiles are all dead
        Fight = "Hostiles are all dead. Generate a new set of hostiles"
    End If

Else
    Fight = "Buccaneers are all dead :(. Suggest building or loading a new buccaneer group"
End If
End Function

通过调用语句使用私有类方法 GroupAttack

Private Sub GroupAttack(attackersGroup As clsGroup, defendersGroup As clsGroup)
'implements the attack of one group on another

Dim victimNo As Integer
Dim randomNumber As Integer
Dim attacker As clsCharacter
Dim damage As Integer
Dim defender As clsCharacter
Randomize

For Each attacker In attackersGroup.members

    'check if attacker is still alive
    If attacker.health > 0 Then

        'check if any defenders are still alive because there's no point attacking dead defenders
        If defendersGroup.aliveCount > 0 Then

            'do some damage on a defender
            If defendersGroup.count > 0 Then
                'choose a random hostile
                victimNo = Int(((Rnd() * defendersGroup.aliveCount) + 1))

                'find an alive victim
                memberid = 0
                j = 0
                Do While j < victimNo
                    memberid = memberid + 1
                    If defendersGroup.members(memberid).health > 0 Then
                        j = j + 1
                    End If
                Loop
                'reset our victimno to the live victim
                victimNo = memberid

                damage = defendersGroup.character(victimNo).attack(attacker.strength)

                If damage <> 0 Then  'attacker hit
                    mScript = mScript & attacker.name & " hits " & _
                    defendersGroup.character(victimNo).name & " for " & damage & " damage"

                    If defendersGroup.character(victimNo).health = 0 Then
                        mScript = mScript & " and kills " & defendersGroup.character(victimNo).name
                    End If
                    mScript = mScript & vbCrLf

                Else 'attacker missed
                    mScript = mScript & attacker.name & " missed " & defendersGroup.character(victimNo).name & vbCrLf
                End If

            End If

        End If

    End If

Next attacker   
End Sub

这就是你需要做的一切,就像一个魅力

于 2017-02-11T15:45:56.887 回答
0

在 COM 中,对象实例的类型和对象变量的类型是有区别的。特别是,对象变量的类型表现为接口类型。每种类型都至少实现一个接口(本身),但类型也可以实现其他接口。这种能力被用来伪造继承。

在某些框架中,如果类Foo有一个私有成员Bar,那么任何类型的非空变量都Foo将持有对包含该成员的某个类对象的引用。该成员可能无法被任何外部代码访问,但它会存在,因此可以从Foo.

但是,因为 COM 类变量类型的行为类似于接口而不是可继承的类类型,所以不能保证类型变量Foo将引用具有任何Foo非公共成员的对象。虽然编译器可以知道Me它将始终引用当前对象,该对象将是实际类型,但可以访问Foo其私有成员的唯一对象意味着编译器没有真正的理由支持点-基于私有成员的取消引用。FooMe

于 2013-01-13T04:06:54.690 回答