假设您在名为Module1
的模块中有此代码:
Option Explicit
Private Type TSomething
Foo As Integer
Bar As Integer
End Type
Public Something As TSomething
在等效的C#代码中,如果您创建Something
字段public
,代码将不再编译,因为不一致的可访问性 - 类型该领域的可访问性低于该领域本身。这是有道理的。
但是在VBA中,您可以在Module2
中使用此代码:
Sub DoSomething()
Module1.Something.Bar = 42
Debug.Print Module1.Something.Bar
End Sub
你在输入时获得了IntelliSense,它会编译并运行,并输出42
。
为什么呢?从COM的角度来看,它是如何工作的?它是语言规范的一部分吗?
答案 0 :(得分:3)
根据我的评论,VBA公开了一个私有类型,就像暴露私有枚举一样。
VBA假设您可以在使用上下文中使用TypeInfo,但它不允许您声明或创建这些类型或枚举的实例。
此C++ answer部分提供了信息:
访问控制适用于名称
名称的访问说明符与其类型
无关
但是在标准模块中考虑私有类型可能很有用,因为喜欢 a" PublicNotCreatable"类。如果您提供公共包装器,则可以在主机模块外部访问该类型。
但是当Type在公共类模块中时,VBA会以不同的方式处理事情!
这是Module1
展开的广告:
Option Explicit
Private Type TSomething
Foo As Integer
Bar As Integer
End Type
Public Type TOtherThing
Foo As Integer
Bar As Integer
End Type
Public Type TWrapperThing
Something As TSomething
End Type
Public Something As TSomething
Public Otherthing As TOtherThing
Public Wrapperthing As TWrapperThing
Public Function GetSomething() As TSomething
GetSomething.Foo = 1
End Function
Public Function GetOtherthing() As TOtherThing
GetOtherthing.Foo = 1
End Function
Module2
已展开:
Option Explicit
Sub DoThings()
'Compile Error: User-defined type not defined
'Dim oSomething As TSomething
Dim vSomething As Variant
Dim oOtherthing As Module1.TOtherThing
Dim vOtherthing As Variant
Dim oWrapperthing As Module1.TWrapperThing
Module1.Something.Foo = 42
Module1.Otherthing.Foo = 42
Module1.Wrapperthing.Something.Foo = 42
'Compile Error: Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions
'vSomething = Module1.Something
'vOtherthing = Module1.Otherthing
oOtherthing = Module1.Otherthing
oOtherthing.Foo = 43
'Is 43 > 42?
Debug.Assert oOtherthing.Foo > Module1.Otherthing.Foo
'Compile Errors: "GetSomething" User-defined type not defined
'Module1.GetSomething.Foo = 42
'Module1.GetSomething().Foo = 42
Module1.GetOtherthing.Foo = 42
Module1.GetOtherthing().Foo = 42
End Sub