函数使用智能感知接受多个枚举
Posted
技术标签:
【中文标题】函数使用智能感知接受多个枚举【英文标题】:Function uses intellisense to accept multiple Enums 【发布时间】:2017-08-15 15:23:55 【问题描述】:我在 VBA 中声明了一个枚举
Enum myEnum
valA = 3
valB = 17
valC = 20
End Enum
我想要一个函数,它接受此 Enum 指定的值的任意组合,并在您输入它们时使用 Intellisense。即,它会提示我可以输入的可能值。
现在,如果我可以选择我的 Enum 中的值是 2 的幂,那么我可能会按照 Chip Pearson 在his section on Composite Values 中建议的那样做,即
Function myFunction(val As myEnum)
'...
End Function
用法
Debug.Print myFunction(valA + valB) 'with intellisense
但是我的枚举不遵循这种模式,所以我无法辨别是输入了valA + valB
,还是输入了valC
。因此我想知道:
有没有办法将数组/不确定数量的变量传递给函数,同时仍然使用 Intellisense 来建议可能的值?
【问题讨论】:
不。 ParamArray 允许任意变量参数,但它是一种变体类型,因此没有智能感知。如果可能的话,位掩码(复合)是最优雅的方式。唯一的其他选择需要额外的设置代码,例如传递一个强类型数组。 你为什么不使用 2 的幂如果你知道这是怎么做的,它可以工作并且保持 IntelliSense?跨度> @Mat'sMug 不幸的是,我无法选择枚举中的值,它们是我想枚举的 magic numbers(微软提出的)的选择. 使用 2 的幂枚举作为查找值(在字典/选择案例实用程序函数中)以获取真实值? 微软想出了他们?如果这些值不是 2 的幂,则枚举不意味着用作复合值。实际的枚举是什么? 【参考方案1】:不,没有。标志枚举正是为此使用 2 的幂。
Public Enum Foo
V1 = 2 ^ 0
V2 = 2 ^ 1
V3 = 2 ^ 2
V4 = 2 ^ 3
V5 = 2 ^ 4
'...
End Enum
这样做的原因是它们允许您使用按位逻辑来确定哪些位是“打开”的,给定一个复合值,例如 5
,它只能是 4 + 1
:
Power 2^5 2^4 2^3 2^2 2^1 2^0
Value 32 16 8 4 2 1
Bit 0 0 0 1 0 1
与already mentioned 一样,另一种方法是使用ParamArray
参数,但它只能是Variant
,并且只能传递ByRef
,这不仅意味着你失去了IntelliSense,你也失去了传递参数值ByVal
的语义安全性(好吧,你的代码隐式 传递了它ByRef
无论如何)。
因此,要么您想出一种方法来“映射”单个“神奇的基础值”枚举成员以标记枚举成员(幂为 2),要么放弃 IntelliSense。
Private Function GetFlag(ByVal value As MyEnum) As MyFlagEnum
Static converter As Scripting.Dictionary
If converter Is Nothing Then
Set converter = New Scripting.Dictionary
With converter
.Add MyEnum.valA, MyFlagEnum.ValueA
.Add MyEnum.valB, MyFlagEnum.ValueB
.Add MyEnum.valC, MyFlagEnum.ValueC
.Add MyEnum.valD, MyFlagEnum.ValueD
.Add MyEnum.valE, MyFlagEnum.ValueE
End With
End If
GetFlag = converter(value)
End Function
然后你可以在拉取映射值后将它们组合起来:
Debug.Print MyFunction(GetFlag(valA) + GetFlag(valB)) ' intellisense everywhere!
MyFunction
采用 MyFlagEnum
值。
如果基础值具有特定含义并且它们是刻在石头上的并且MyFunction
需要使用它们,则需要另一个函数将单个 FlagEnum 值“解包”为单个“MyEnum”值:
Private Function GetFromFlag(ByVal value As MyFlagEnum) As MyEnum
Static converter As Scripting.Dictionary
If converter Is Nothing Then
Set converter = New Scripting.Dictionary
With converter
.Add MyFlagEnum.ValueA, MyFlagEnum.valA
.Add MyFlagEnum.ValueB, MyFlagEnum.valB
.Add MyFlagEnum.ValueC, MyFlagEnum.valC
.Add MyFlagEnum.ValueD, MyFlagEnum.valD
.Add MyFlagEnum.ValueE, MyFlagEnum.valE
End With
End If
GetFromFlag = converter(value)
End Function
然后,再次使用该函数与单个未组合值。所以MyFunction
需要做的第一件事是确定哪些单独的标志是“打开”的,然后GetFromFlag
每个人都可以获得单独的非标志枚举值。
这应该很有用:
Private Function HasFlag(ByVal composite As Long, ByVal flag As Long) As Boolean
HasFlag = (composite And flag) = flag
End Function
【讨论】:
以上是关于函数使用智能感知接受多个枚举的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio C++ 2005-2013 中的智能感知缺少函数定义
如何在 Visual Studio Code 中为 Unity 函数名称获取智能感知?