我已经在这个问题上做了一些调查,并且真的能够找到很多东西。事实上,我很确定我已经知道了这个问题的答案,但我会问,以防万一有一些我不知道的先进技术。 (具有相当高的概率)你能声明一个结构/类的属性的名称,或者至少通过某种构造函数重命名它们吗?
基本上,长话短说我试图创建一个有效地为你提供位域样式标志的联合结构,但是你可以在声明时指定标志的名称,使代码看起来更清晰。我知道你通过建立一个整数(char / double / whatever)和一个bitfield结构的联合在C中做同样的事情。我基本上可以这样做的事情:
Public status as BitField({"PowerOn","Ready","Error",...})
基本结构如下:
Public Structure (or Class) BitField
Private _value as UInt16
Public Property value as UInt16
Get
Return _value
End Get
Set(input as UInt16)
_value = input
End Set
End Property
Public Property bit0 As Boolean
Get
Return ((_value And &H1UI) > 0)
End Get
Set(input as Boolean)
If input Then
_value = _value Or &H1UI
Else
_value = _value And &HFFFEUI
End If
End Set
End Property
(and so on for bit 1 through 15)
Public Sub New(ByVal names() As String)
...Something that redeclairs/renames/equates "bit0" with names(0)...
...Something that redeclairs/renames/equates "bit1" with names(1)...
and so on
End Sub
End Structure/Class
之后我可以调用status.Error来获取或设置第三位,但如果我想,我可以将status.value与掩码进行比较以检查某个状态。
我的意思是我在C中知道你只是这样做:
union {
unsigned int value;
struct {
unsigned PowerOn:1;
unsigned Ready:1;
unsigned Error:1;
...
};
} status;
但是我希望得到同样水平的清洁度#34;在我的代码中,没有必要有一个巨大的声明,我必须复制,每次我想使用它时重写一半。
正如我在开始时所说的那样,我假设我已经离开了基地而没有办法做我在VB.Net中提出的建议,但是如果有人有任何想法的话我很乐意听到他们的声音。答案 0 :(得分:1)
您无法在运行时创建或重命名属性,因为编译器需要知道它们是什么。根据评论,这里有一种方法可以为每个创建一个具有不同含义或地图的不同BitSetter
对象,并使用最少的新代码:
Public Class BitSetter(Of T)
Private value As UInt16
Public Sub New(v As UInt16)
value = v
End Sub
Public Sub SetBit(n As T, b As Boolean)
' do stuff
End Sub
Public Function GetBit(n As T) As Boolean
' do stuff
End Function
End Class
Boolean input
param的原因是什么,但为了清楚起见,我会将其分解为自己的方法。SetValue(n As UInt16)
方法是设置它的另一种方法。Option Strict
;像value = value Or &H1UI
这样的代码包含一个隐式转换而不会编译。 使类通用(Of T)
允许您为每个品种定义一组不同的语义:
Private Enum FooBits
Flag
[Error]
Green
'...
End Enum
Private Enum BarBits
Red = 0
Charm = 1
Quark = 3
Ziggy = 4
End Enum
如果您不知道,Flag
将用于位(0),Error
用于1等,因此请按顺序或明确。第二组给出了显式值,而不是定义不应该使用的[Reserved]之类的东西,它只是跳过该值,因此 cant 被使用。创建和使用它们:
' starting value of 3:
Dim fooB As New BitSetter(Of FooBits)(3)
Dim barB As New BitSetter(Of BarBits)(6) ' value = 6
Dim b As Boolean
b = fooB.GetBit(FooBits.Error)
barB.SetBit(BarBits.Quark, True)
FooBits
版本只允许FooBits Enum
的成员使用其方法。类型是强制执行的,并且在代码中清楚使用了哪个位/项。尝试将BarBits
的成员与fooB
一起使用(使用Option Strict)将导致编译错误。它还会阻止传递幻数值:
barB.SetBit(2, True)
因此,对于每个新的部分或地图,您需要的唯一新代码是新的Enum
集(和BitSetter
实例)。
如果你想让它更简洁(例如b = barB.Get(BarBits.Ziggy)
),你需要转义类中的方法名称,因为它们是关键字:
Public Sub [Set](n As T, b As Boolean)
Public Function [Get](n As T) As Boolean